Skip to content

Commit

Permalink
added in iam adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
SanaaYousaf committed Feb 27, 2023
1 parent f4b26fc commit 059d0a2
Show file tree
Hide file tree
Showing 15 changed files with 400 additions and 85 deletions.
35 changes: 35 additions & 0 deletions internal/adapters/cloud/aws/iam/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,41 @@ func (a *adapter) adaptServerCertificate(certInfo iamtypes.ServerCertificateMeta

return &iam.ServerCertificate{
Metadata: metadata,
Name: defsecTypes.String(*certInfo.ServerCertificateName, metadata),
Expiration: expiration,
}, nil
}

func (a *adapter) adaptVirtualMfadevices(state *state.State) error {
a.Tracker().SetServiceLabel("Discovering Virtual Mfa Devices...")

var mfadevices []iamtypes.VirtualMFADevice

input := &iamapi.ListVirtualMFADevicesInput{}
for {
certsOutput, err := a.api.ListVirtualMFADevices(a.Context(), input)
if err != nil {
return err
}
mfadevices = append(mfadevices, certsOutput.VirtualMFADevices...)
a.Tracker().SetTotalResources(len(mfadevices))
if !certsOutput.IsTruncated {
break
}
input.Marker = certsOutput.Marker
}

a.Tracker().SetServiceLabel("Adapting virtual mfa devices...")

state.AWS.IAM.VirtualMfaDevices = concurrency.Adapt(mfadevices, a.RootAdapter, a.adaptVirtualMfaDevice)
return nil
}

func (a *adapter) adaptVirtualMfaDevice(mfaapi iamtypes.VirtualMFADevice) (*iam.VirtualMfaDevice, error) {
metadata := a.CreateMetadataFromARN(*mfaapi.User.Arn)

return &iam.VirtualMfaDevice{
Metadata: metadata,
SerialNumber: defsecTypes.String(*mfaapi.SerialNumber, metadata),
}, nil
}
23 changes: 14 additions & 9 deletions internal/adapters/cloud/aws/iam/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func (a *adapter) Adapt(root *aws.RootAdapter, state *state.State) error {
return err
}

if err := a.adaptVirtualMfadevices(state); err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -84,15 +88,16 @@ func (a *adapter) adaptPasswordPolicy(state *state.State) error {
minimumLength = int(*policy.MinimumPasswordLength)
}
state.AWS.IAM.PasswordPolicy = iam.PasswordPolicy{
Metadata: metadata,
ReusePreventionCount: types.Int(reusePrevention, metadata),
RequireLowercase: types.Bool(policy.RequireLowercaseCharacters, metadata),
RequireUppercase: types.Bool(policy.RequireUppercaseCharacters, metadata),
RequireNumbers: types.Bool(policy.RequireNumbers, metadata),
RequireSymbols: types.Bool(policy.RequireSymbols, metadata),
ExpirePasswords: types.Bool(policy.ExpirePasswords, metadata),
MaxAgeDays: types.Int(maxAge, metadata),
MinimumLength: types.Int(minimumLength, metadata),
Metadata: metadata,
ReusePreventionCount: types.Int(reusePrevention, metadata),
RequireLowercase: types.Bool(policy.RequireLowercaseCharacters, metadata),
RequireUppercase: types.Bool(policy.RequireUppercaseCharacters, metadata),
RequireNumbers: types.Bool(policy.RequireNumbers, metadata),
RequireSymbols: types.Bool(policy.RequireSymbols, metadata),
ExpirePasswords: types.Bool(policy.ExpirePasswords, metadata),
MaxAgeDays: types.Int(maxAge, metadata),
MinimumLength: types.Int(minimumLength, metadata),
AllowUsersToChangePassword: types.Bool(policy.AllowUsersToChangePassword, metadata),
}

return nil
Expand Down
5 changes: 3 additions & 2 deletions internal/adapters/cloud/aws/iam/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ func (a *adapter) adaptPolicy(apiPolicy iamtypes.Policy) (*iam.Policy, error) {
}

return &iam.Policy{
Metadata: metadata,
Name: name,
Metadata: metadata,
DefaultVersionId: defsecTypes.String(*apiPolicy.DefaultVersionId, metadata),
Name: name,
Document: iam.Document{
Metadata: metadata,
Parsed: *document,
Expand Down
29 changes: 26 additions & 3 deletions internal/adapters/cloud/aws/iam/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,32 @@ func (a *adapter) adaptRole(apiRole iamtypes.Role) (*iam.Role, error) {

metadata := a.CreateMetadataFromARN(*apiRole.Arn)

var tags []iam.Tag
output, err := a.api.GetRole(a.Context(), &iamapi.GetRoleInput{
RoleName: apiRole.RoleName,
})
if err != nil {
output = nil
}
if output != nil {
for range output.Role.Tags {
tags = append(tags, iam.Tag{
Metadata: metadata,
})
}
}

var lastuseddate types.TimeValue
if output.Role.RoleLastUsed != nil {
lastuseddate = types.Time(*output.Role.RoleLastUsed.LastUsedDate, metadata)
}

return &iam.Role{
Metadata: metadata,
Name: types.String(*apiRole.RoleName, metadata),
Policies: policies,
Metadata: metadata,
Name: types.String(*apiRole.RoleName, metadata),
Tags: tags,
LastUsedDate: lastuseddate,
AssumeRolePolicyDocument: types.String(*apiRole.AssumeRolePolicyDocument, metadata),
Policies: policies,
}, nil
}
70 changes: 61 additions & 9 deletions internal/adapters/cloud/aws/iam/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ import (
"time"

"github.com/aquasecurity/defsec/pkg/concurrency"
defsecTypes "github.com/aquasecurity/defsec/pkg/types"

"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/state"
defsecTypes "github.com/aquasecurity/defsec/pkg/types"
iamapi "github.com/aws/aws-sdk-go-v2/service/iam"
iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types"
)
Expand Down Expand Up @@ -75,6 +74,37 @@ func (a *adapter) getMFADevices(user iamtypes.User) ([]iam.MFADevice, error) {
return devices, nil
}

func (a *adapter) getSSHPublicKeys(user iamtypes.User) ([]iam.SSHPublicKey, error) {
input := &iamapi.ListSSHPublicKeysInput{
UserName: user.UserName,
}
var apiDevices []iamtypes.SSHPublicKeyMetadata
for {
output, err := a.api.ListSSHPublicKeys(a.Context(), input)
if err != nil {
return nil, err
}
apiDevices = append(apiDevices, output.SSHPublicKeys...)
if !output.IsTruncated {
break
}
input.Marker = output.Marker
}
var sshPublickey []iam.SSHPublicKey

for _, key := range apiDevices {
metadata := a.CreateMetadata(*key.SSHPublicKeyId)
sshPublickey = append(sshPublickey, iam.SSHPublicKey{
Metadata: metadata,
ID: defsecTypes.String(*key.SSHPublicKeyId, metadata),
Status: defsecTypes.String(string(key.Status), metadata),
UploadDate: defsecTypes.Time(*key.UploadDate, metadata),
})
}
return sshPublickey, nil

}

func (a *adapter) getUserGroups(apiUser iamtypes.User) []iam.Group {
var groups []iam.Group

Expand Down Expand Up @@ -206,6 +236,11 @@ func (a *adapter) adaptUser(apiUser iamtypes.User) (*iam.User, error) {
return nil, err
}

sshKeys, err := a.getSSHPublicKeys(apiUser)
if err != nil {
return nil, err
}

lastAccess := defsecTypes.TimeUnresolvable(metadata)
if apiUser.PasswordLastUsed != nil {
lastAccess = defsecTypes.Time(*apiUser.PasswordLastUsed, metadata)
Expand All @@ -216,13 +251,30 @@ func (a *adapter) adaptUser(apiUser iamtypes.User) (*iam.User, error) {
username = defsecTypes.String(*apiUser.UserName, metadata)
}

var tags []iam.Tag
output, err := a.api.GetUser(a.Context(), &iamapi.GetUserInput{
UserName: apiUser.UserName,
})
if err != nil {
output = nil
}
if output != nil {
for range output.User.Tags {
tags = append(tags, iam.Tag{
Metadata: metadata,
})
}
}

return &iam.User{
Metadata: metadata,
Name: username,
Groups: groups,
Policies: policies,
AccessKeys: keys,
MFADevices: mfaDevices,
LastAccess: lastAccess,
Metadata: metadata,
Name: username,
Groups: groups,
Policies: policies,
AccessKeys: keys,
MFADevices: mfaDevices,
SSHPublicKeys: sshKeys,
LastAccess: lastAccess,
Tags: tags,
}, nil
}
28 changes: 15 additions & 13 deletions internal/adapters/cloudformation/aws/iam/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ import (
func Adapt(cfFile parser.FileContext) iam.IAM {
return iam.IAM{
PasswordPolicy: iam.PasswordPolicy{
Metadata: defsecTypes.NewUnmanagedMetadata(),
ReusePreventionCount: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
RequireLowercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireUppercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireNumbers: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireSymbols: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
ExpirePasswords: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
MaxAgeDays: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
MinimumLength: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
Metadata: defsecTypes.NewUnmanagedMetadata(),
ReusePreventionCount: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
RequireLowercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireUppercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireNumbers: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireSymbols: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
ExpirePasswords: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
MaxAgeDays: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
MinimumLength: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
AllowUsersToChangePassword: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
},
Policies: getPolicies(cfFile),
Groups: getGroups(cfFile),
Users: getUsers(cfFile),
Roles: getRoles(cfFile),
Policies: getPolicies(cfFile),
Groups: getGroups(cfFile),
Users: getUsers(cfFile),
Roles: getRoles(cfFile),
ServerCertificates: getServerCertificates(cfFile),
}
}
41 changes: 38 additions & 3 deletions internal/adapters/cloudformation/aws/iam/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ func getRoles(ctx parser.FileContext) (roles []iam.Role) {
roleName := roleResource.GetStringProperty("RoleName")

roles = append(roles, iam.Role{
Metadata: roleResource.Metadata(),
Name: roleName,
Policies: getPoliciesDocs(policyProp),
Metadata: roleResource.Metadata(),
Name: roleName,
Policies: getPoliciesDocs(policyProp),
Tags: getTags(roleResource),
LastUsedDate: defsecTypes.TimeUnresolvable(roleResource.Metadata()),
AssumeRolePolicyDocument: roleResource.GetStringProperty("AssumeRolePolicyDocument"),
})
}
return roles
Expand All @@ -58,6 +61,7 @@ func getUsers(ctx parser.FileContext) (users []iam.User) {
LastAccess: defsecTypes.TimeUnresolvable(userResource.Metadata()),
Policies: getPoliciesDocs(policyProp),
AccessKeys: getAccessKeys(ctx, userName.Value()),
Tags: getTags(userResource),
})
}
return users
Expand Down Expand Up @@ -123,3 +127,34 @@ func getPoliciesDocs(policiesProp *parser.Property) []iam.Policy {
}
return policies
}

func getServerCertificates(ctx parser.FileContext) []iam.ServerCertificate {
var certs []iam.ServerCertificate

certResources := ctx.GetResourcesByType("")
for _, r := range certResources {
certs = append(certs, iam.ServerCertificate{
Metadata: r.Metadata(),
Name: r.GetStringProperty("ServerCertificateName"),
Expiration: defsecTypes.TimeUnresolvable(r.Metadata()),
})
}
return certs
}

func getTags(resource *parser.Resource) []iam.Tag {

var tags []iam.Tag

tagList := resource.GetProperty("Tags")
if tagList.IsNil() || tagList.IsNotList() {
return tags
}

for _, t := range tagList.AsList() {
tags = append(tags, iam.Tag{
Metadata: t.Metadata(),
})
}
return tags
}
11 changes: 6 additions & 5 deletions internal/adapters/terraform/aws/iam/adapt.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (

func Adapt(modules terraform.Modules) iam.IAM {
return iam.IAM{
PasswordPolicy: adaptPasswordPolicy(modules),
Policies: adaptPolicies(modules),
Groups: adaptGroups(modules),
Users: adaptUsers(modules),
Roles: adaptRoles(modules),
PasswordPolicy: adaptPasswordPolicy(modules),
Policies: adaptPolicies(modules),
Groups: adaptGroups(modules),
Users: adaptUsers(modules),
Roles: adaptRoles(modules),
ServerCertificates: adaptCertificate(modules),
}
}
23 changes: 23 additions & 0 deletions internal/adapters/terraform/aws/iam/cert.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package iam

import (
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/terraform"
"github.com/aquasecurity/defsec/pkg/types"
)

func adaptCertificate(modules terraform.Modules) []iam.ServerCertificate {
var certificates []iam.ServerCertificate

for _, module := range modules {
for _, resource := range module.GetResourcesByType("") {
certificates = append(certificates, iam.ServerCertificate{
Metadata: resource.GetMetadata(),
Name: resource.GetAttribute("name").AsStringValueOrDefault("", resource),
Expiration: types.TimeUnresolvable(resource.GetMetadata()),
})

}
}
return certificates
}
22 changes: 14 additions & 8 deletions internal/adapters/terraform/aws/iam/passwords.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,15 @@ import (
func adaptPasswordPolicy(modules terraform.Modules) iam.PasswordPolicy {

policy := iam.PasswordPolicy{
Metadata: defsecTypes.NewUnmanagedMetadata(),
ReusePreventionCount: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
RequireLowercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireUppercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireNumbers: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireSymbols: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
MaxAgeDays: defsecTypes.IntDefault(math.MaxInt, defsecTypes.NewUnmanagedMetadata()),
MinimumLength: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
Metadata: defsecTypes.NewUnmanagedMetadata(),
ReusePreventionCount: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
RequireLowercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireUppercase: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireNumbers: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
RequireSymbols: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
MaxAgeDays: defsecTypes.IntDefault(math.MaxInt, defsecTypes.NewUnmanagedMetadata()),
MinimumLength: defsecTypes.IntDefault(0, defsecTypes.NewUnmanagedMetadata()),
AllowUsersToChangePassword: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
}

passwordPolicies := modules.GetResourcesByType("aws_iam_account_password_policy")
Expand Down Expand Up @@ -53,6 +54,11 @@ func adaptPasswordPolicy(modules terraform.Modules) iam.PasswordPolicy {
} else {
policy.RequireSymbols = defsecTypes.BoolDefault(false, policyBlock.GetMetadata())
}
if attr := policyBlock.GetAttribute("allow_users_to_change_password"); attr.IsNotNil() {
policy.AllowUsersToChangePassword = defsecTypes.BoolExplicit(attr.IsTrue(), attr.GetMetadata())
} else {
policy.AllowUsersToChangePassword = defsecTypes.BoolDefault(false, policyBlock.GetMetadata())
}
if attr := policyBlock.GetAttribute("password_reuse_prevention"); attr.IsNumber() {
value := attr.AsNumber()
policy.ReusePreventionCount = defsecTypes.IntExplicit(int(value), attr.GetMetadata())
Expand Down
Loading

0 comments on commit 059d0a2

Please sign in to comment.