diff --git a/internal/adapters/cloud/aws/iam/certs.go b/internal/adapters/cloud/aws/iam/certs.go index 79fd4963b..ffb37beea 100644 --- a/internal/adapters/cloud/aws/iam/certs.go +++ b/internal/adapters/cloud/aws/iam/certs.go @@ -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 +} diff --git a/internal/adapters/cloud/aws/iam/iam.go b/internal/adapters/cloud/aws/iam/iam.go index f33681155..5e4d29d61 100644 --- a/internal/adapters/cloud/aws/iam/iam.go +++ b/internal/adapters/cloud/aws/iam/iam.go @@ -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 } @@ -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 diff --git a/internal/adapters/cloud/aws/iam/policy.go b/internal/adapters/cloud/aws/iam/policy.go index f6a9513fc..6146329ea 100644 --- a/internal/adapters/cloud/aws/iam/policy.go +++ b/internal/adapters/cloud/aws/iam/policy.go @@ -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, diff --git a/internal/adapters/cloud/aws/iam/role.go b/internal/adapters/cloud/aws/iam/role.go index a436afb61..15ffbd097 100644 --- a/internal/adapters/cloud/aws/iam/role.go +++ b/internal/adapters/cloud/aws/iam/role.go @@ -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 } diff --git a/internal/adapters/cloud/aws/iam/user.go b/internal/adapters/cloud/aws/iam/user.go index 91da4a91e..1a80ada35 100644 --- a/internal/adapters/cloud/aws/iam/user.go +++ b/internal/adapters/cloud/aws/iam/user.go @@ -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" ) @@ -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 @@ -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) @@ -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 } diff --git a/internal/adapters/cloudformation/aws/iam/iam.go b/internal/adapters/cloudformation/aws/iam/iam.go index 85a83e7d0..9a7ff1f92 100644 --- a/internal/adapters/cloudformation/aws/iam/iam.go +++ b/internal/adapters/cloudformation/aws/iam/iam.go @@ -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), } } diff --git a/internal/adapters/cloudformation/aws/iam/policy.go b/internal/adapters/cloudformation/aws/iam/policy.go index 93290f833..fea44445a 100644 --- a/internal/adapters/cloudformation/aws/iam/policy.go +++ b/internal/adapters/cloudformation/aws/iam/policy.go @@ -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 @@ -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 @@ -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 +} diff --git a/internal/adapters/terraform/aws/iam/adapt.go b/internal/adapters/terraform/aws/iam/adapt.go index 226b23aad..a05846992 100644 --- a/internal/adapters/terraform/aws/iam/adapt.go +++ b/internal/adapters/terraform/aws/iam/adapt.go @@ -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), } } diff --git a/internal/adapters/terraform/aws/iam/cert.go b/internal/adapters/terraform/aws/iam/cert.go new file mode 100644 index 000000000..b1ad10e12 --- /dev/null +++ b/internal/adapters/terraform/aws/iam/cert.go @@ -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 +} diff --git a/internal/adapters/terraform/aws/iam/passwords.go b/internal/adapters/terraform/aws/iam/passwords.go index 5d3dc238f..e5632162e 100644 --- a/internal/adapters/terraform/aws/iam/passwords.go +++ b/internal/adapters/terraform/aws/iam/passwords.go @@ -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") @@ -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()) diff --git a/internal/adapters/terraform/aws/iam/roles.go b/internal/adapters/terraform/aws/iam/roles.go index de8811ac7..7c3da016c 100644 --- a/internal/adapters/terraform/aws/iam/roles.go +++ b/internal/adapters/terraform/aws/iam/roles.go @@ -51,9 +51,12 @@ func mapRoles(modules terraform.Modules) (map[string]iam.Role, map[string]struct roleMap := make(map[string]iam.Role) for _, roleBlock := range modules.GetResourcesByType("aws_iam_role") { role := iam.Role{ - Metadata: roleBlock.GetMetadata(), - Name: roleBlock.GetAttribute("name").AsStringValueOrDefault("", roleBlock), - Policies: nil, + Metadata: roleBlock.GetMetadata(), + Name: roleBlock.GetAttribute("name").AsStringValueOrDefault("", roleBlock), + Tags: gettags(roleBlock), + LastUsedDate: defsecTypes.TimeUnresolvable(roleBlock.GetMetadata()), + AssumeRolePolicyDocument: roleBlock.GetAttribute("assume_role_policy").AsStringValueOrDefault("", roleBlock), + Policies: nil, } if inlineBlock := roleBlock.GetBlock("inline_policy"); inlineBlock.IsNotNil() { policy := iam.Policy{ diff --git a/internal/adapters/terraform/aws/iam/users.go b/internal/adapters/terraform/aws/iam/users.go index 76e7fa46e..a245f5a43 100644 --- a/internal/adapters/terraform/aws/iam/users.go +++ b/internal/adapters/terraform/aws/iam/users.go @@ -28,13 +28,15 @@ func adaptUsers(modules terraform.Modules) []iam.User { user, ok := userMap[userBlock.ID()] if !ok { user = iam.User{ - Metadata: userBlock.GetMetadata(), - Name: userBlock.GetAttribute("name").AsStringValueOrDefault("", userBlock), - Groups: nil, - Policies: nil, - AccessKeys: nil, - MFADevices: nil, - LastAccess: defsecTypes.TimeUnresolvable(userBlock.GetMetadata()), + Metadata: userBlock.GetMetadata(), + Name: userBlock.GetAttribute("name").AsStringValueOrDefault("", userBlock), + Groups: nil, + Policies: nil, + AccessKeys: nil, + MFADevices: nil, + SSHPublicKeys: adaptSSHPublicKey(policyBlock, modules), + Tags: gettags(userBlock), + LastAccess: defsecTypes.TimeUnresolvable(userBlock.GetMetadata()), } } user.Policies = append(user.Policies, policy) @@ -156,3 +158,29 @@ func adaptAccessKey(block *terraform.Block) (*iam.AccessKey, error) { } return &key, nil } + +func adaptSSHPublicKey(block *terraform.Block, modules terraform.Modules) []iam.SSHPublicKey { + + sshKeyResources := modules.GetReferencingResources(block, " aws_iam_user_ssh_key", "username") + var sshkey []iam.SSHPublicKey + + for _, key := range sshKeyResources { + sshkey = append(sshkey, iam.SSHPublicKey{ + Metadata: key.GetMetadata(), + ID: key.GetAttribute("ssh_public_key_id").AsStringValueOrDefault("", key), + Status: key.GetAttribute("status").AsStringValueOrDefault("", key), + UploadDate: defsecTypes.TimeUnresolvable(key.GetMetadata()), + }) + } + return sshkey +} + +func gettags(block *terraform.Block) []iam.Tag { + var tags []iam.Tag + for _, t := range block.GetBlocks("tags") { + tags = append(tags, iam.Tag{ + Metadata: t.GetMetadata(), + }) + } + return tags +} diff --git a/pkg/providers/aws/iam/iam.go b/pkg/providers/aws/iam/iam.go index 8d3783488..1bb8decab 100755 --- a/pkg/providers/aws/iam/iam.go +++ b/pkg/providers/aws/iam/iam.go @@ -12,18 +12,26 @@ type IAM struct { Users []User Roles []Role ServerCertificates []ServerCertificate + VirtualMfaDevices []VirtualMfaDevice } type ServerCertificate struct { Metadata defsecTypes.Metadata + Name defsecTypes.StringValue Expiration defsecTypes.TimeValue } +type VirtualMfaDevice struct { + Metadata defsecTypes.Metadata + SerialNumber defsecTypes.StringValue +} + type Policy struct { - Metadata defsecTypes.Metadata - Name defsecTypes.StringValue - Document Document - Builtin defsecTypes.BoolValue + Metadata defsecTypes.Metadata + DefaultVersionId defsecTypes.StringValue + Name defsecTypes.StringValue + Document Document + Builtin defsecTypes.BoolValue } type Document struct { @@ -55,13 +63,15 @@ type Group struct { } type User struct { - Metadata defsecTypes.Metadata - Name defsecTypes.StringValue - Groups []Group - Policies []Policy - AccessKeys []AccessKey - MFADevices []MFADevice - LastAccess defsecTypes.TimeValue + Metadata defsecTypes.Metadata + Name defsecTypes.StringValue + Groups []Group + Policies []Policy + AccessKeys []AccessKey + MFADevices []MFADevice + SSHPublicKeys []SSHPublicKey + Tags []Tag + LastAccess defsecTypes.TimeValue } func (u *User) HasLoggedIn() bool { @@ -73,6 +83,12 @@ type MFADevice struct { IsVirtual defsecTypes.BoolValue } +type SSHPublicKey struct { + Metadata defsecTypes.Metadata + ID defsecTypes.StringValue + Status defsecTypes.StringValue + UploadDate defsecTypes.TimeValue +} type AccessKey struct { Metadata defsecTypes.Metadata AccessKeyId defsecTypes.StringValue @@ -82,9 +98,12 @@ type AccessKey struct { } type Role struct { - Metadata defsecTypes.Metadata - Name defsecTypes.StringValue - Policies []Policy + Metadata defsecTypes.Metadata + Name defsecTypes.StringValue + AssumeRolePolicyDocument defsecTypes.StringValue + Tags []Tag + LastUsedDate defsecTypes.TimeValue + Policies []Policy } func (d Document) MetadataFromIamGo(r ...iamgo.Range) defsecTypes.Metadata { @@ -109,3 +128,7 @@ func (d Document) MetadataFromIamGo(r ...iamgo.Range) defsecTypes.Metadata { } return m } + +type Tag struct { + Metadata defsecTypes.Metadata +} diff --git a/pkg/providers/aws/iam/passwords.go b/pkg/providers/aws/iam/passwords.go index 6e8bfef68..45723e23a 100755 --- a/pkg/providers/aws/iam/passwords.go +++ b/pkg/providers/aws/iam/passwords.go @@ -5,13 +5,14 @@ import ( ) type PasswordPolicy struct { - Metadata defsecTypes.Metadata - ReusePreventionCount defsecTypes.IntValue - RequireLowercase defsecTypes.BoolValue - RequireUppercase defsecTypes.BoolValue - RequireNumbers defsecTypes.BoolValue - RequireSymbols defsecTypes.BoolValue - ExpirePasswords defsecTypes.BoolValue - MaxAgeDays defsecTypes.IntValue - MinimumLength defsecTypes.IntValue + Metadata defsecTypes.Metadata + ReusePreventionCount defsecTypes.IntValue + RequireLowercase defsecTypes.BoolValue + RequireUppercase defsecTypes.BoolValue + RequireNumbers defsecTypes.BoolValue + RequireSymbols defsecTypes.BoolValue + ExpirePasswords defsecTypes.BoolValue + MaxAgeDays defsecTypes.IntValue + MinimumLength defsecTypes.IntValue + AllowUsersToChangePassword defsecTypes.BoolValue } diff --git a/pkg/rego/schemas/cloud.json b/pkg/rego/schemas/cloud.json index d0a68808b..884189bc0 100644 --- a/pkg/rego/schemas/cloud.json +++ b/pkg/rego/schemas/cloud.json @@ -1884,6 +1884,13 @@ "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.User" } + }, + "virtualmfadevices": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.VirtualMfaDevice" + } } } }, @@ -1899,6 +1906,10 @@ "github.com.aquasecurity.defsec.pkg.providers.aws.iam.PasswordPolicy": { "type": "object", "properties": { + "allowuserstochangepassword": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.BoolValue" + }, "expirepasswords": { "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.BoolValue" @@ -1940,6 +1951,10 @@ "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.BoolValue" }, + "defaultversionid": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" + }, "document": { "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.Document" @@ -1953,6 +1968,14 @@ "github.com.aquasecurity.defsec.pkg.providers.aws.iam.Role": { "type": "object", "properties": { + "assumerolepolicydocument": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" + }, + "lastuseddate": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.TimeValue" + }, "name": { "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" @@ -1963,6 +1986,30 @@ "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.Policy" } + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.Tag" + } + } + } + }, + "github.com.aquasecurity.defsec.pkg.providers.aws.iam.SSHPublicKey": { + "type": "object", + "properties": { + "id": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" + }, + "status": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" + }, + "uploaddate": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.TimeValue" } } }, @@ -1972,9 +2019,16 @@ "expiration": { "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.TimeValue" + }, + "name": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" } } }, + "github.com.aquasecurity.defsec.pkg.providers.aws.iam.Tag": { + "type": "object" + }, "github.com.aquasecurity.defsec.pkg.providers.aws.iam.User": { "type": "object", "properties": { @@ -2013,6 +2067,29 @@ "type": "object", "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.Policy" } + }, + "sshpublickeys": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.SSHPublicKey" + } + }, + "tags": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.providers.aws.iam.Tag" + } + } + } + }, + "github.com.aquasecurity.defsec.pkg.providers.aws.iam.VirtualMfaDevice": { + "type": "object", + "properties": { + "serialnumber": { + "type": "object", + "$ref": "#/definitions/github.com.aquasecurity.defsec.pkg.types.StringValue" } } },