Skip to content

Commit

Permalink
added cloud adapter for generate_credential_report apicall
Browse files Browse the repository at this point in the history
  • Loading branch information
SanaaYousaf committed Feb 27, 2023
1 parent 059d0a2 commit 074e2f0
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 0 deletions.
4 changes: 4 additions & 0 deletions internal/adapters/cloud/aws/iam/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ func (a *adapter) Adapt(root *aws.RootAdapter, state *state.State) error {
return err
}

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

return nil
}

Expand Down
103 changes: 103 additions & 0 deletions internal/adapters/cloud/aws/iam/reports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package iam

import (
"strings"
"time"

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

"github.com/aquasecurity/defsec/pkg/concurrency"
"github.com/aquasecurity/defsec/pkg/providers/aws/iam"
"github.com/aquasecurity/defsec/pkg/state"
iamapi "github.com/aws/aws-sdk-go-v2/service/iam"
)

func (a *adapter) adaptCredentialReport(state *state.State) error {
a.Tracker().SetServiceLabel("Discovering credential reports...")

input := &iamapi.GenerateCredentialReportInput{}
for {
_, err := a.api.GenerateCredentialReport(a.Context(), input)
if err != nil && strings.Contains(err.Error(), "ReportInProgress") {
time.Sleep(5 * time.Second)
} else {
break
}
if err != nil {
return err
}

}

var reportData [][]string
var reportErr error

for {
resp, err := a.api.GetCredentialReport(a.Context(), &iamapi.GetCredentialReportInput{})
if err != nil {
return err
}
reportBytes := resp.Content
reportStr := string(reportBytes)
// Parse CSV content
reportLines := strings.Split(reportStr, "\n")
if len(reportLines) == 0 {
continue
}

reportData = make([][]string, len(reportLines)-1)
for i, line := range reportLines[1:] {
fields := strings.Split(line, ",")
reportData[i] = make([]string, len(fields))
for i, line := range reportLines[1:] {
fields := strings.Split(line, ",")
reportData[i] = make([]string, len(fields))
copy(reportData[i], fields)
}
}
reportErr = nil
break
}
if reportErr != nil {
return reportErr
}

a.Tracker().SetServiceLabel("Adapting server certificates...")

state.AWS.IAM.CredentialReports = concurrency.Adapt(reportData, a.RootAdapter, a.adaptReport)
return nil
}

func (a *adapter) adaptReport(reportdata []string) (*iam.CredentialReport, error) {

var report iam.CredentialReport

metadata := a.CreateMetadataFromARN(reportdata[1])
report = iam.CredentialReport{
Metadata: metadata,
User: defsecTypes.String(reportdata[0], metadata),
Arn: defsecTypes.String(reportdata[1], metadata),
User_creation_time: defsecTypes.String(reportdata[2], metadata),
Password_enabled: defsecTypes.String(reportdata[3], metadata),
Password_last_used: defsecTypes.String(reportdata[4], metadata),
Password_last_changed: defsecTypes.String(reportdata[5], metadata),
Password_next_rotation: defsecTypes.String(reportdata[6], metadata),
Mfa_active: defsecTypes.String(reportdata[7], metadata),
Access_key_1_active: defsecTypes.String(reportdata[8], metadata),
Access_key_1_last_rotated: defsecTypes.String(reportdata[9], metadata),
Access_key_1_last_used_date: defsecTypes.String(reportdata[10], metadata),
Access_key_1_last_used_region: defsecTypes.String(reportdata[11], metadata),
Access_key_1_last_used_service: defsecTypes.String(reportdata[12], metadata),
Access_key_2_active: defsecTypes.String(reportdata[13], metadata),
Access_key_2_last_rotated: defsecTypes.String(reportdata[14], metadata),
Access_key_2_last_used_date: defsecTypes.String(reportdata[15], metadata),
Access_key_2_last_used_region: defsecTypes.String(reportdata[16], metadata),
Access_key_2_last_used_service: defsecTypes.String(reportdata[17], metadata),
Cert_1_active: defsecTypes.String(reportdata[18], metadata),
Cert_1_last_rotated: defsecTypes.String(reportdata[19], metadata),
Cert_2_active: defsecTypes.String(reportdata[20], metadata),
Cert_2_last_rotated: defsecTypes.String(reportdata[21], metadata),
}

return &report, nil
}
27 changes: 27 additions & 0 deletions pkg/providers/aws/iam/iam.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type IAM struct {
Roles []Role
ServerCertificates []ServerCertificate
VirtualMfaDevices []VirtualMfaDevice
CredentialReports []CredentialReport
}

type ServerCertificate struct {
Expand Down Expand Up @@ -132,3 +133,29 @@ func (d Document) MetadataFromIamGo(r ...iamgo.Range) defsecTypes.Metadata {
type Tag struct {
Metadata defsecTypes.Metadata
}

type CredentialReport struct {
Metadata defsecTypes.Metadata
User defsecTypes.StringValue
Arn defsecTypes.StringValue
User_creation_time defsecTypes.StringValue
Password_enabled defsecTypes.StringValue
Password_last_used defsecTypes.StringValue
Password_last_changed defsecTypes.StringValue
Password_next_rotation defsecTypes.StringValue
Mfa_active defsecTypes.StringValue
Access_key_1_active defsecTypes.StringValue
Access_key_1_last_rotated defsecTypes.StringValue
Access_key_1_last_used_date defsecTypes.StringValue
Access_key_1_last_used_region defsecTypes.StringValue
Access_key_1_last_used_service defsecTypes.StringValue
Access_key_2_active defsecTypes.StringValue
Access_key_2_last_rotated defsecTypes.StringValue
Access_key_2_last_used_date defsecTypes.StringValue
Access_key_2_last_used_region defsecTypes.StringValue
Access_key_2_last_used_service defsecTypes.StringValue
Cert_1_active defsecTypes.StringValue
Cert_1_last_rotated defsecTypes.StringValue
Cert_2_active defsecTypes.StringValue
Cert_2_last_rotated defsecTypes.StringValue
}
100 changes: 100 additions & 0 deletions pkg/rego/schemas/cloud.json
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,99 @@
}
}
},
"git.luolix.top.aquasecurity.defsec.pkg.providers.aws.iam.CredentialReport": {
"type": "object",
"properties": {
"access_key_1_active": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_1_last_rotated": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_1_last_used_date": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_1_last_used_region": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_1_last_used_service": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_2_active": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_2_last_rotated": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_2_last_used_date": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_2_last_used_region": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"access_key_2_last_used_service": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"arn": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"cert_1_active": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"cert_1_last_rotated": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"cert_2_active": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"cert_2_last_rotated": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"mfa_active": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"password_enabled": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"password_last_changed": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"password_last_used": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"password_next_rotation": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"user": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
},
"user_creation_time": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.types.StringValue"
}
}
},
"git.luolix.top.aquasecurity.defsec.pkg.providers.aws.iam.Document": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -1846,6 +1939,13 @@
"git.luolix.top.aquasecurity.defsec.pkg.providers.aws.iam.IAM": {
"type": "object",
"properties": {
"credentialreports": {
"type": "array",
"items": {
"type": "object",
"$ref": "#/definitions/git.luolix.top.aquasecurity.defsec.pkg.providers.aws.iam.CredentialReport"
}
},
"groups": {
"type": "array",
"items": {
Expand Down

0 comments on commit 074e2f0

Please sign in to comment.