github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/aws/iam/users.go (about)

     1  package iam
     2  
     3  import (
     4  	"github.com/google/uuid"
     5  	"github.com/khulnasoft-lab/defsec/pkg/providers/aws/iam"
     6  	"github.com/khulnasoft-lab/defsec/pkg/terraform"
     7  	defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types"
     8  )
     9  
    10  func adaptUsers(modules terraform.Modules) []iam.User {
    11  	userMap, policyMap := mapUsers(modules)
    12  	for _, policyBlock := range modules.GetResourcesByType("aws_iam_user_policy") {
    13  		if _, ok := policyMap[policyBlock.ID()]; ok {
    14  			continue
    15  		}
    16  		userAttr := policyBlock.GetAttribute("user")
    17  		if userAttr.IsNil() {
    18  			continue
    19  		}
    20  		userBlock, err := modules.GetReferencedBlock(userAttr, policyBlock)
    21  		if err != nil {
    22  			continue
    23  		}
    24  		policy, err := parsePolicy(policyBlock, modules)
    25  		if err != nil {
    26  			continue
    27  		}
    28  		user, ok := userMap[userBlock.ID()]
    29  		if !ok {
    30  			user = iam.User{
    31  				Metadata:   userBlock.GetMetadata(),
    32  				Name:       userBlock.GetAttribute("name").AsStringValueOrDefault("", userBlock),
    33  				Groups:     nil,
    34  				Policies:   nil,
    35  				AccessKeys: nil,
    36  				MFADevices: nil,
    37  				LastAccess: defsecTypes.TimeUnresolvable(userBlock.GetMetadata()),
    38  			}
    39  		}
    40  		user.Policies = append(user.Policies, policy)
    41  		userMap[userBlock.ID()] = user
    42  	}
    43  	for _, block := range modules.GetResourcesByType("aws_iam_access_key") {
    44  		if userAttr := block.GetAttribute("user"); userAttr.IsString() {
    45  			var found bool
    46  			for _, user := range userMap {
    47  				if user.Name.EqualTo(userAttr.Value().AsString()) {
    48  					found = true
    49  					break
    50  				}
    51  			}
    52  			if found {
    53  				continue
    54  			}
    55  			key, err := adaptAccessKey(block)
    56  			if err != nil {
    57  				continue
    58  			}
    59  			userMap[uuid.NewString()] = iam.User{
    60  				Metadata:   block.GetMetadata(),
    61  				Name:       userAttr.AsStringValueOrDefault("", block),
    62  				AccessKeys: []iam.AccessKey{*key},
    63  				LastAccess: defsecTypes.TimeUnresolvable(block.GetMetadata()),
    64  			}
    65  		}
    66  	}
    67  
    68  	var output []iam.User
    69  	for _, user := range userMap {
    70  		output = append(output, user)
    71  	}
    72  	return output
    73  }
    74  
    75  // nolint
    76  func mapUsers(modules terraform.Modules) (map[string]iam.User, map[string]struct{}) {
    77  	userMap := make(map[string]iam.User)
    78  	policyMap := make(map[string]struct{})
    79  	for _, userBlock := range modules.GetResourcesByType("aws_iam_user") {
    80  		user := iam.User{
    81  			Metadata:   userBlock.GetMetadata(),
    82  			Name:       userBlock.GetAttribute("name").AsStringValueOrDefault("", userBlock),
    83  			LastAccess: defsecTypes.TimeUnresolvable(userBlock.GetMetadata()),
    84  		}
    85  
    86  		for _, block := range modules.GetResourcesByType("aws_iam_user_policy") {
    87  			if !sameProvider(userBlock, block) {
    88  				continue
    89  			}
    90  			if userAttr := block.GetAttribute("user"); userAttr.IsString() {
    91  				if userAttr.Equals(user.Name.Value()) {
    92  					policy, err := parsePolicy(block, modules)
    93  					if err != nil {
    94  						continue
    95  					}
    96  					user.Policies = append(user.Policies, policy)
    97  					policyMap[block.ID()] = struct{}{}
    98  				}
    99  			}
   100  		}
   101  
   102  		for _, block := range modules.GetResourcesByType("aws_iam_user_policy_attachment") {
   103  			if !sameProvider(userBlock, block) {
   104  				continue
   105  			}
   106  			if userAttr := block.GetAttribute("user"); userAttr.IsString() {
   107  				if userAttr.Equals(user.Name.Value()) {
   108  					policyAttr := block.GetAttribute("policy_arn")
   109  
   110  					policyBlock, err := modules.GetReferencedBlock(policyAttr, block)
   111  					if err != nil {
   112  						continue
   113  					}
   114  					policy, err := parsePolicy(policyBlock, modules)
   115  					if err != nil {
   116  						continue
   117  					}
   118  					user.Policies = append(user.Policies, policy)
   119  					policyMap[block.ID()] = struct{}{}
   120  				}
   121  			}
   122  		}
   123  
   124  		for _, block := range modules.GetResourcesByType("aws_iam_access_key") {
   125  			if !sameProvider(userBlock, block) {
   126  				continue
   127  			}
   128  			if userAttr := block.GetAttribute("user"); (userAttr.IsString() && userAttr.Equals(user.Name.Value())) || userAttr.ReferencesBlock(userBlock) {
   129  				key, err := adaptAccessKey(block)
   130  				if err != nil {
   131  					continue
   132  				}
   133  				user.AccessKeys = append(user.AccessKeys, *key)
   134  			}
   135  		}
   136  
   137  		userMap[userBlock.ID()] = user
   138  	}
   139  	return userMap, policyMap
   140  
   141  }
   142  
   143  func adaptAccessKey(block *terraform.Block) (*iam.AccessKey, error) {
   144  
   145  	active := defsecTypes.BoolDefault(true, block.GetMetadata())
   146  	if activeAttr := block.GetAttribute("status"); activeAttr.IsString() {
   147  		active = defsecTypes.Bool(activeAttr.Equals("Inactive"), activeAttr.GetMetadata())
   148  	}
   149  
   150  	key := iam.AccessKey{
   151  		Metadata:     block.GetMetadata(),
   152  		AccessKeyId:  defsecTypes.StringUnresolvable(block.GetMetadata()),
   153  		CreationDate: defsecTypes.TimeUnresolvable(block.GetMetadata()),
   154  		LastAccess:   defsecTypes.TimeUnresolvable(block.GetMetadata()),
   155  		Active:       active,
   156  	}
   157  	return &key, nil
   158  }