From 75b254342907f5a3a5ca977690a6e0126d1112ed Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Fri, 14 Feb 2025 22:25:48 -0800 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=90=9B=20fix=20`aws.s3.bucket.policy`?= =?UTF-8?q?=20resource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change allows running `aws.s3.bucket.policy` when in discovery mode. ``` cnspec shell aws --discover s3-buckets ``` Also, fixes the issue discovered at https://github.com/mondoohq/cnquery/pull/5218 where we noticed that the policy resource doesn't implement the `id()` func properly. Closes https://github.com/mondoohq/cnquery/issues/5169 Signed-off-by: Salim Afiune Maya --- providers/aws/resources/aws.lr | 8 ++- providers/aws/resources/aws.lr.go | 28 +++++++--- providers/aws/resources/aws.lr.manifest.yaml | 4 ++ providers/aws/resources/aws_s3.go | 59 ++++++++++++-------- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/providers/aws/resources/aws.lr b/providers/aws/resources/aws.lr index 0922a5c0bc..94be3b2c8a 100644 --- a/providers/aws/resources/aws.lr +++ b/providers/aws/resources/aws.lr @@ -1822,17 +1822,19 @@ private aws.s3.bucket.corsrule @defaults("name") { } // Amazon S3 bucket policy -private aws.s3.bucket.policy @defaults("name version") { +private aws.s3.bucket.policy @defaults("bucketName exists version") { // Unique ID for the policy id string - // Name for the policy - name string + // Bucket name that this policy belongs + bucketName string // Document for the policy document string // Version of the policy version() string // List of statements for the policy statements() []dict + // Whether the bucket policy exists + exists bool } diff --git a/providers/aws/resources/aws.lr.go b/providers/aws/resources/aws.lr.go index 5989a408fe..0d2f838079 100644 --- a/providers/aws/resources/aws.lr.go +++ b/providers/aws/resources/aws.lr.go @@ -463,7 +463,7 @@ func init() { Create: createAwsS3BucketCorsrule, }, "aws.s3.bucket.policy": { - // to override args, implement: initAwsS3BucketPolicy(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Init: initAwsS3BucketPolicy, Create: createAwsS3BucketPolicy, }, "aws.applicationAutoscaling": { @@ -2879,8 +2879,8 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.s3.bucket.policy.id": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetId()).ToDataRes(types.String) }, - "aws.s3.bucket.policy.name": func(r plugin.Resource) *plugin.DataRes { - return (r.(*mqlAwsS3BucketPolicy).GetName()).ToDataRes(types.String) + "aws.s3.bucket.policy.bucketName": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsS3BucketPolicy).GetBucketName()).ToDataRes(types.String) }, "aws.s3.bucket.policy.document": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetDocument()).ToDataRes(types.String) @@ -2891,6 +2891,9 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.s3.bucket.policy.statements": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetStatements()).ToDataRes(types.Array(types.Dict)) }, + "aws.s3.bucket.policy.exists": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsS3BucketPolicy).GetExists()).ToDataRes(types.Bool) + }, "aws.applicationAutoscaling.namespace": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsApplicationAutoscaling).GetNamespace()).ToDataRes(types.String) }, @@ -8206,8 +8209,8 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsS3BucketPolicy).Id, ok = plugin.RawToTValue[string](v.Value, v.Error) return }, - "aws.s3.bucket.policy.name": func(r plugin.Resource, v *llx.RawData) (ok bool) { - r.(*mqlAwsS3BucketPolicy).Name, ok = plugin.RawToTValue[string](v.Value, v.Error) + "aws.s3.bucket.policy.bucketName": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsS3BucketPolicy).BucketName, ok = plugin.RawToTValue[string](v.Value, v.Error) return }, "aws.s3.bucket.policy.document": func(r plugin.Resource, v *llx.RawData) (ok bool) { @@ -8222,6 +8225,10 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsS3BucketPolicy).Statements, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) return }, + "aws.s3.bucket.policy.exists": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsS3BucketPolicy).Exists, ok = plugin.RawToTValue[bool](v.Value, v.Error) + return + }, "aws.applicationAutoscaling.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlAwsApplicationAutoscaling).__id, ok = v.Value.(string) return @@ -20837,10 +20844,11 @@ type mqlAwsS3BucketPolicy struct { __id string // optional: if you define mqlAwsS3BucketPolicyInternal it will be used here Id plugin.TValue[string] - Name plugin.TValue[string] + BucketName plugin.TValue[string] Document plugin.TValue[string] Version plugin.TValue[string] Statements plugin.TValue[[]interface{}] + Exists plugin.TValue[bool] } // createAwsS3BucketPolicy creates a new instance of this resource @@ -20884,8 +20892,8 @@ func (c *mqlAwsS3BucketPolicy) GetId() *plugin.TValue[string] { return &c.Id } -func (c *mqlAwsS3BucketPolicy) GetName() *plugin.TValue[string] { - return &c.Name +func (c *mqlAwsS3BucketPolicy) GetBucketName() *plugin.TValue[string] { + return &c.BucketName } func (c *mqlAwsS3BucketPolicy) GetDocument() *plugin.TValue[string] { @@ -20904,6 +20912,10 @@ func (c *mqlAwsS3BucketPolicy) GetStatements() *plugin.TValue[[]interface{}] { }) } +func (c *mqlAwsS3BucketPolicy) GetExists() *plugin.TValue[bool] { + return &c.Exists +} + // mqlAwsApplicationAutoscaling for the aws.applicationAutoscaling resource type mqlAwsApplicationAutoscaling struct { MqlRuntime *plugin.Runtime diff --git a/providers/aws/resources/aws.lr.manifest.yaml b/providers/aws/resources/aws.lr.manifest.yaml index 56768b6c6d..251caf9f0c 100755 --- a/providers/aws/resources/aws.lr.manifest.yaml +++ b/providers/aws/resources/aws.lr.manifest.yaml @@ -2845,7 +2845,11 @@ resources: desc: | Bucket policies grant permission to your Amazon S3 resources fields: + bucketName: + min_mondoo_version: 9.0.0 document: {} + exists: + min_mondoo_version: 9.0.0 id: {} name: {} statements: {} diff --git a/providers/aws/resources/aws_s3.go b/providers/aws/resources/aws_s3.go index 03ddbace69..7fe6563c68 100644 --- a/providers/aws/resources/aws_s3.go +++ b/providers/aws/resources/aws_s3.go @@ -114,6 +114,17 @@ func (a *mqlAwsS3) buckets() ([]interface{}, error) { return res, nil } +func initAwsS3BucketPolicy(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { + // reuse the init func for the bucket + _, s3bucketResource, err := initAwsS3Bucket(runtime, args) + if err != nil { + return args, nil, err + } + // then use it to get its policy + policyResource := s3bucketResource.(*mqlAwsS3Bucket).GetPolicy() + return args, policyResource.Data, nil +} + func initAwsS3Bucket(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { // NOTE: bucket only initializes with arn and name if len(args) >= 2 { @@ -180,12 +191,13 @@ func (a *mqlAwsS3Bucket) id() (string, error) { return a.Arn.Data, nil } -func emptyAwsS3BucketPolicy(runtime *plugin.Runtime) (*mqlAwsS3BucketPolicy, error) { - res, err := CreateResource(runtime, "aws.s3.bucket.policy", map[string]*llx.RawData{ - "name": llx.StringData(""), +func (a *mqlAwsS3Bucket) emptyAwsS3BucketPolicy() (*mqlAwsS3BucketPolicy, error) { + res, err := CreateResource(a.MqlRuntime, "aws.s3.bucket.policy", map[string]*llx.RawData{ + "bucketName": llx.StringData(a.Name.Data), "document": llx.StringData("{}"), "version": llx.StringData(""), "id": llx.StringData(""), + "exists": llx.BoolData(false), "statements": llx.ArrayData([]interface{}{}, types.Dict), }) if err != nil { @@ -207,26 +219,34 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { }) if err != nil { if isNotFoundForS3(err) { - return emptyAwsS3BucketPolicy(a.MqlRuntime) + return a.emptyAwsS3BucketPolicy() } return nil, err } if policy != nil && policy.Policy != nil { + parsedPolicy, err := parsePolicy(*policy.Policy) + if err != nil { + return nil, err + } // create the policy resource mqlS3BucketPolicy, err := CreateResource(a.MqlRuntime, "aws.s3.bucket.policy", map[string]*llx.RawData{ - "name": llx.StringData(bucketname), - "document": llx.StringDataPtr(policy.Policy), + "id": llx.StringData(parsedPolicy.Id), + "bucketName": llx.StringData(bucketname), + "version": llx.StringData(parsedPolicy.Version), + "document": llx.StringDataPtr(policy.Policy), + "exists": llx.BoolData(true), }) if err != nil { return nil, err } + return mqlS3BucketPolicy.(*mqlAwsS3BucketPolicy), nil } // no bucket policy found, return nil for the policy - return emptyAwsS3BucketPolicy(a.MqlRuntime) + return a.emptyAwsS3BucketPolicy() } func (a *mqlAwsS3Bucket) tags() (map[string]interface{}, error) { @@ -438,7 +458,7 @@ func (a *mqlAwsS3Bucket) public() (bool, error) { statusOutput, err := svc.GetBucketPolicyStatus(ctx, &s3.GetBucketPolicyStatusInput{ Bucket: &bucketname, }) - if err != nil { + if err != nil && !isNotFoundForS3(err) { return false, err } if statusOutput != nil && @@ -698,25 +718,20 @@ func (a *mqlAwsS3BucketCorsrule) id() (string, error) { } func (a *mqlAwsS3BucketPolicy) id() (string, error) { - policy, err := a.parsePolicyDocument() - if err != nil || policy == nil { - return "none", err - } - - a.Id = plugin.TValue[string]{Data: policy.Id, State: plugin.StateIsSet} - return policy.Id, nil + // NOTE that `policy.Id` might or might not exist and, + // it is NOT unique for s3 bucket policies. what we need + // here is the bucket name, which is unique globally. + return fmt.Sprintf("aws.s3.bucket/%s/policy", a.BucketName.Data), nil } func (a *mqlAwsS3BucketPolicy) parsePolicyDocument() (*awspolicy.S3BucketPolicy, error) { - data := a.Document.Data + return parsePolicy(a.Document.Data) +} +func parsePolicy(document string) (*awspolicy.S3BucketPolicy, error) { var policy awspolicy.S3BucketPolicy - err := json.Unmarshal([]byte(data), &policy) - if err != nil { - return nil, err - } - - return &policy, nil + err := json.Unmarshal([]byte(document), &policy) + return &policy, err } func (a *mqlAwsS3BucketPolicy) version() (string, error) { From 01b8dd5ddbf6217c022f1564934c7700ee335718 Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Wed, 19 Feb 2025 16:35:51 -0800 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=94=84=20do=20not=20create=20bucket?= =?UTF-8?q?=20policy=20if=20not=20exists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Salim Afiune Maya --- providers/aws/resources/aws.lr | 7 +++---- providers/aws/resources/aws.lr.go | 24 ++++++++++++------------ providers/aws/resources/aws_s3.go | 24 +++--------------------- 3 files changed, 18 insertions(+), 37 deletions(-) diff --git a/providers/aws/resources/aws.lr b/providers/aws/resources/aws.lr index 94be3b2c8a..d0a6016e38 100644 --- a/providers/aws/resources/aws.lr +++ b/providers/aws/resources/aws.lr @@ -1822,9 +1822,11 @@ private aws.s3.bucket.corsrule @defaults("name") { } // Amazon S3 bucket policy -private aws.s3.bucket.policy @defaults("bucketName exists version") { +private aws.s3.bucket.policy @defaults("bucketName version") { // Unique ID for the policy id string + // Deprecated + name string // Bucket name that this policy belongs bucketName string // Document for the policy @@ -1833,11 +1835,8 @@ private aws.s3.bucket.policy @defaults("bucketName exists version") { version() string // List of statements for the policy statements() []dict - // Whether the bucket policy exists - exists bool } - // AWS Application Auto Scaling aws.applicationAutoscaling @defaults("namespace") { init(namespace string) diff --git a/providers/aws/resources/aws.lr.go b/providers/aws/resources/aws.lr.go index 0d2f838079..dae69ead0a 100644 --- a/providers/aws/resources/aws.lr.go +++ b/providers/aws/resources/aws.lr.go @@ -2879,6 +2879,9 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.s3.bucket.policy.id": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetId()).ToDataRes(types.String) }, + "aws.s3.bucket.policy.name": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAwsS3BucketPolicy).GetName()).ToDataRes(types.String) + }, "aws.s3.bucket.policy.bucketName": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetBucketName()).ToDataRes(types.String) }, @@ -2891,9 +2894,6 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "aws.s3.bucket.policy.statements": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsS3BucketPolicy).GetStatements()).ToDataRes(types.Array(types.Dict)) }, - "aws.s3.bucket.policy.exists": func(r plugin.Resource) *plugin.DataRes { - return (r.(*mqlAwsS3BucketPolicy).GetExists()).ToDataRes(types.Bool) - }, "aws.applicationAutoscaling.namespace": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlAwsApplicationAutoscaling).GetNamespace()).ToDataRes(types.String) }, @@ -8209,6 +8209,10 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsS3BucketPolicy).Id, ok = plugin.RawToTValue[string](v.Value, v.Error) return }, + "aws.s3.bucket.policy.name": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAwsS3BucketPolicy).Name, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, "aws.s3.bucket.policy.bucketName": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlAwsS3BucketPolicy).BucketName, ok = plugin.RawToTValue[string](v.Value, v.Error) return @@ -8225,10 +8229,6 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlAwsS3BucketPolicy).Statements, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) return }, - "aws.s3.bucket.policy.exists": func(r plugin.Resource, v *llx.RawData) (ok bool) { - r.(*mqlAwsS3BucketPolicy).Exists, ok = plugin.RawToTValue[bool](v.Value, v.Error) - return - }, "aws.applicationAutoscaling.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlAwsApplicationAutoscaling).__id, ok = v.Value.(string) return @@ -20844,11 +20844,11 @@ type mqlAwsS3BucketPolicy struct { __id string // optional: if you define mqlAwsS3BucketPolicyInternal it will be used here Id plugin.TValue[string] + Name plugin.TValue[string] BucketName plugin.TValue[string] Document plugin.TValue[string] Version plugin.TValue[string] Statements plugin.TValue[[]interface{}] - Exists plugin.TValue[bool] } // createAwsS3BucketPolicy creates a new instance of this resource @@ -20892,6 +20892,10 @@ func (c *mqlAwsS3BucketPolicy) GetId() *plugin.TValue[string] { return &c.Id } +func (c *mqlAwsS3BucketPolicy) GetName() *plugin.TValue[string] { + return &c.Name +} + func (c *mqlAwsS3BucketPolicy) GetBucketName() *plugin.TValue[string] { return &c.BucketName } @@ -20912,10 +20916,6 @@ func (c *mqlAwsS3BucketPolicy) GetStatements() *plugin.TValue[[]interface{}] { }) } -func (c *mqlAwsS3BucketPolicy) GetExists() *plugin.TValue[bool] { - return &c.Exists -} - // mqlAwsApplicationAutoscaling for the aws.applicationAutoscaling resource type mqlAwsApplicationAutoscaling struct { MqlRuntime *plugin.Runtime diff --git a/providers/aws/resources/aws_s3.go b/providers/aws/resources/aws_s3.go index 7fe6563c68..791ec91ce2 100644 --- a/providers/aws/resources/aws_s3.go +++ b/providers/aws/resources/aws_s3.go @@ -191,21 +191,6 @@ func (a *mqlAwsS3Bucket) id() (string, error) { return a.Arn.Data, nil } -func (a *mqlAwsS3Bucket) emptyAwsS3BucketPolicy() (*mqlAwsS3BucketPolicy, error) { - res, err := CreateResource(a.MqlRuntime, "aws.s3.bucket.policy", map[string]*llx.RawData{ - "bucketName": llx.StringData(a.Name.Data), - "document": llx.StringData("{}"), - "version": llx.StringData(""), - "id": llx.StringData(""), - "exists": llx.BoolData(false), - "statements": llx.ArrayData([]interface{}{}, types.Dict), - }) - if err != nil { - return nil, err - } - return res.(*mqlAwsS3BucketPolicy), nil -} - func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { conn := a.MqlRuntime.Connection.(*connection.AwsConnection) @@ -217,10 +202,7 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { policy, err := svc.GetBucketPolicy(ctx, &s3.GetBucketPolicyInput{ Bucket: &bucketname, }) - if err != nil { - if isNotFoundForS3(err) { - return a.emptyAwsS3BucketPolicy() - } + if err != nil && !isNotFoundForS3(err) { return nil, err } @@ -233,10 +215,10 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { mqlS3BucketPolicy, err := CreateResource(a.MqlRuntime, "aws.s3.bucket.policy", map[string]*llx.RawData{ "id": llx.StringData(parsedPolicy.Id), + "name": llx.StringData(bucketname), "bucketName": llx.StringData(bucketname), "version": llx.StringData(parsedPolicy.Version), "document": llx.StringDataPtr(policy.Policy), - "exists": llx.BoolData(true), }) if err != nil { return nil, err @@ -246,7 +228,7 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { } // no bucket policy found, return nil for the policy - return a.emptyAwsS3BucketPolicy() + return nil, nil } func (a *mqlAwsS3Bucket) tags() (map[string]interface{}, error) { From 99d3c8346b575b056d21e605f98bc405c22cc44b Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Thu, 20 Feb 2025 14:57:04 -0800 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=90=9B=20set=20policy=20to=20`plugin.?= =?UTF-8?q?StateIsNull`=20when=20not=20found?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Salim Afiune Maya --- providers/aws/resources/aws_s3.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/providers/aws/resources/aws_s3.go b/providers/aws/resources/aws_s3.go index 791ec91ce2..341dcccff6 100644 --- a/providers/aws/resources/aws_s3.go +++ b/providers/aws/resources/aws_s3.go @@ -202,7 +202,11 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { policy, err := svc.GetBucketPolicy(ctx, &s3.GetBucketPolicyInput{ Bucket: &bucketname, }) - if err != nil && !isNotFoundForS3(err) { + if err != nil { + if isNotFoundForS3(err) { + a.Policy.State = plugin.StateIsNull | plugin.StateIsSet + return nil, nil + } return nil, err } From 958b932b7239165bdad5452f51571059772ea8cc Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Fri, 21 Feb 2025 09:24:15 -0800 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=90=9B=20fix=20accessing=20aws.s3.buc?= =?UTF-8?q?ket.policy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Salim Afiune Maya --- providers/aws/resources/aws_s3.go | 55 ++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/providers/aws/resources/aws_s3.go b/providers/aws/resources/aws_s3.go index 341dcccff6..b19719ca14 100644 --- a/providers/aws/resources/aws_s3.go +++ b/providers/aws/resources/aws_s3.go @@ -122,7 +122,21 @@ func initAwsS3BucketPolicy(runtime *plugin.Runtime, args map[string]*llx.RawData } // then use it to get its policy policyResource := s3bucketResource.(*mqlAwsS3Bucket).GetPolicy() - return args, policyResource.Data, nil + if policyResource != nil { + return args, policyResource.Data, nil + } + + // no policy found + resource := &mqlAwsS3BucketPolicy{} + resource.Id.State = plugin.StateIsNull | plugin.StateIsSet + resource.Name.State = plugin.StateIsNull | plugin.StateIsSet + resource.Document.State = plugin.StateIsNull | plugin.StateIsSet + resource.Version.State = plugin.StateIsNull | plugin.StateIsSet + resource.Statements.State = plugin.StateIsNull | plugin.StateIsSet + resource.BucketName = plugin.TValue[string]{ + Data: s3bucketResource.(*mqlAwsS3Bucket).GetName().Data, State: plugin.StateIsSet, + } + return args, resource, nil } func initAwsS3Bucket(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) { @@ -144,6 +158,9 @@ func initAwsS3Bucket(runtime *plugin.Runtime, args map[string]*llx.RawData) (map var arn string if args["arn"] != nil { arn = args["arn"].Value.(string) + if !strings.HasPrefix(arn, "arn:aws:s3:") { + return nil, nil, errors.Newf("not a valid bucket ARN '%s'", arn) + } } else { nameVal := args["name"].Value.(string) arn = fmt.Sprintf(s3ArnPattern, nameVal) @@ -211,7 +228,7 @@ func (a *mqlAwsS3Bucket) policy() (*mqlAwsS3BucketPolicy, error) { } if policy != nil && policy.Policy != nil { - parsedPolicy, err := parsePolicy(*policy.Policy) + parsedPolicy, err := parseS3BucketPolicy(*policy.Policy) if err != nil { return nil, err } @@ -454,23 +471,21 @@ func (a *mqlAwsS3Bucket) public() (bool, error) { } // If that didn't work, fetch the bucket policy manually and parse it - bucketPolicyResource, err := a.policy() - if err != nil { - return false, err - } - - bucketPolicy, err := bucketPolicyResource.parsePolicyDocument() - if err != nil { - return false, err - } - - for _, statement := range bucketPolicy.Statements { - if statement.Effect != "Allow" { - continue + bucketPolicyResource := a.GetPolicy() + if bucketPolicyResource.State == plugin.StateIsSet { + bucketPolicy, err := bucketPolicyResource.Data.parsePolicyDocument() + if err != nil { + return false, err } - if awsPrincipal, ok := statement.Principal["AWS"]; ok { - if slices.Contains(awsPrincipal, "*") { - return true, nil + + for _, statement := range bucketPolicy.Statements { + if statement.Effect != "Allow" { + continue + } + if awsPrincipal, ok := statement.Principal["AWS"]; ok { + if slices.Contains(awsPrincipal, "*") { + return true, nil + } } } } @@ -711,10 +726,10 @@ func (a *mqlAwsS3BucketPolicy) id() (string, error) { } func (a *mqlAwsS3BucketPolicy) parsePolicyDocument() (*awspolicy.S3BucketPolicy, error) { - return parsePolicy(a.Document.Data) + return parseS3BucketPolicy(a.Document.Data) } -func parsePolicy(document string) (*awspolicy.S3BucketPolicy, error) { +func parseS3BucketPolicy(document string) (*awspolicy.S3BucketPolicy, error) { var policy awspolicy.S3BucketPolicy err := json.Unmarshal([]byte(document), &policy) return &policy, err From d4dfcef42942594b30289c70d395bd087c4bc8d0 Mon Sep 17 00:00:00 2001 From: Salim Afiune Maya Date: Fri, 21 Feb 2025 09:46:57 -0800 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A7=B9=20update=20aws.lr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- providers/aws/resources/aws.lr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/providers/aws/resources/aws.lr b/providers/aws/resources/aws.lr index d0a6016e38..4ba646b5cd 100644 --- a/providers/aws/resources/aws.lr +++ b/providers/aws/resources/aws.lr @@ -1825,7 +1825,7 @@ private aws.s3.bucket.corsrule @defaults("name") { private aws.s3.bucket.policy @defaults("bucketName version") { // Unique ID for the policy id string - // Deprecated + // Deprecated. Use `bucketName` instead name string // Bucket name that this policy belongs bucketName string