github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/cloud/aws/dynamodb/dynamodb.go (about) 1 package dynamodb 2 3 import ( 4 "github.com/aws/aws-sdk-go-v2/aws" 5 dynamodbApi "github.com/aws/aws-sdk-go-v2/service/dynamodb" 6 dynamodbTypes "github.com/aws/aws-sdk-go-v2/service/dynamodb/types" 7 aws2 "github.com/khulnasoft-lab/defsec/internal/adapters/cloud/aws" 8 "github.com/khulnasoft-lab/defsec/pkg/concurrency" 9 "github.com/khulnasoft-lab/defsec/pkg/providers/aws/dynamodb" 10 "github.com/khulnasoft-lab/defsec/pkg/state" 11 defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types" 12 ) 13 14 type adapter struct { 15 *aws2.RootAdapter 16 client *dynamodbApi.Client 17 } 18 19 func init() { 20 aws2.RegisterServiceAdapter(&adapter{}) 21 } 22 23 func (a *adapter) Name() string { 24 return "dynamodb" 25 } 26 27 func (a *adapter) Provider() string { 28 return "aws" 29 } 30 31 func (a *adapter) Adapt(root *aws2.RootAdapter, state *state.State) error { 32 a.RootAdapter = root 33 a.client = dynamodbApi.NewFromConfig(root.SessionConfig()) 34 var err error 35 36 state.AWS.DynamoDB.Tables, err = a.getTables() 37 if err != nil { 38 return err 39 } 40 41 return nil 42 } 43 44 func (a *adapter) getTables() (tables []dynamodb.Table, err error) { 45 46 a.Tracker().SetServiceLabel("Discovering DynamoDB tables...") 47 48 var apiTables []string 49 var input dynamodbApi.ListTablesInput 50 for { 51 output, err := a.client.ListTables(a.Context(), &input) 52 if err != nil { 53 return nil, err 54 } 55 apiTables = append(apiTables, output.TableNames...) 56 a.Tracker().SetTotalResources(len(apiTables)) 57 if output.LastEvaluatedTableName == nil { 58 break 59 } 60 input.ExclusiveStartTableName = output.LastEvaluatedTableName 61 } 62 63 a.Tracker().SetServiceLabel("Adapting DynamoDB tables...") 64 return concurrency.Adapt(apiTables, a.RootAdapter, a.adaptTable), nil 65 66 } 67 68 func (a *adapter) adaptTable(tableName string) (*dynamodb.Table, error) { 69 70 tableMetadata := a.CreateMetadata(tableName) 71 72 table, err := a.client.DescribeTable(a.Context(), &dynamodbApi.DescribeTableInput{ 73 TableName: aws.String(tableName), 74 }) 75 if err != nil { 76 return nil, err 77 } 78 encryption := dynamodb.ServerSideEncryption{ 79 Metadata: tableMetadata, 80 Enabled: defsecTypes.BoolDefault(false, tableMetadata), 81 KMSKeyID: defsecTypes.StringDefault("", tableMetadata), 82 } 83 if table.Table.SSEDescription != nil { 84 85 if table.Table.SSEDescription.Status == dynamodbTypes.SSEStatusEnabled { 86 encryption.Enabled = defsecTypes.BoolDefault(true, tableMetadata) 87 } 88 89 if table.Table.SSEDescription.KMSMasterKeyArn != nil { 90 encryption.KMSKeyID = defsecTypes.StringDefault(*table.Table.SSEDescription.KMSMasterKeyArn, tableMetadata) 91 } 92 } 93 pitRecovery := defsecTypes.Bool(false, tableMetadata) 94 continuousBackup, err := a.client.DescribeContinuousBackups(a.Context(), &dynamodbApi.DescribeContinuousBackupsInput{ 95 TableName: aws.String(tableName), 96 }) 97 98 if err != nil && continuousBackup != nil && continuousBackup.ContinuousBackupsDescription != nil && 99 continuousBackup.ContinuousBackupsDescription.PointInTimeRecoveryDescription != nil { 100 if continuousBackup.ContinuousBackupsDescription.PointInTimeRecoveryDescription.PointInTimeRecoveryStatus == dynamodbTypes.PointInTimeRecoveryStatusEnabled { 101 pitRecovery = defsecTypes.BoolDefault(true, tableMetadata) 102 } 103 104 } 105 return &dynamodb.Table{ 106 Metadata: tableMetadata, 107 ServerSideEncryption: encryption, 108 PointInTimeRecovery: pitRecovery, 109 }, nil 110 }