Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] #567

Open
Aaron-Garrett opened this issue Sep 16, 2024 · 10 comments
Open

[BUG] #567

Aaron-Garrett opened this issue Sep 16, 2024 · 10 comments
Labels
bug Something isn't working

Comments

@Aaron-Garrett
Copy link

Describe the bug
A clear and concise description of what the bug is.

The rule I wrote checking for S3 permissions on wildcard Resource is running and failing on IAM roles without any S3 permissions.

To Reproduce
Please supply:

Example rules and template that results in the error
Template:

rImmutaRdsLambdaRole:
    Type: "AWS::IAM::Role"
    Properties:
      RoleName: immunment
      PermissionsBoundary: !Sub "arn:aws:iam::${AWS::AccountId}:policy/L-Boundary"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service: "rds.amazonaws.com"
            Action: "sts:AssumeRole"
      Policies:
        - PolicyName: "RdsInvokeLambdaPolicy"
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: "Allow"
                Action: "lambda:InvokeFunction"
                Resource: !GetAtt rIImmuta.Arn

CloudFormation Guard Rule:

I KNOW THIS SEEMS TOTALLY UNRELATED TO THE CODE ABOVE BUT THIS IS THE CHECK THAT KEEPS FAILING

# R5.0  Automatically inspect the code for * in S3 folder (prefix) access and present a warning statement to the developer if found

let aws_iam_policies_no_full_access_for_s3 = Resources.*[
  Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "IAM_POLICY_NO_FULL_ACCESS_FOR_S3"
]

let aws_iam_roles_no_full_access_for_s3 = Resources.*[
  Type in [/AWS::IAM::Role/]
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "IAM_ROLE_NO_FULL_ACCESS_FOR_S3"
]

# Checks there is no wildcard in the bucket name in an IAM Role

rule IAM_ROLE_FULL_BUCKET_NAME_USED when %aws_iam_roles_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks the full folder path is used with no wildcards before the second "/" in an IAM Role

rule IAM_ROLE_FULL_FOLDER_PATH_USED when %aws_iam_roles_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks there is no wildcard in the bucket name in an IAM Policy

rule IAM_POLICY_FULL_BUCKET_NAME_USED when %aws_iam_policies_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks the full folder path is used with no wildcards before the second "/" in an IAM Policy

rule IAM_POLICY_FULL_FOLDER_PATH_USED when %aws_iam_policies_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

let s3_no_full_permission = Resources.*[ Type == 'AWS::S3::BucketPolicy'
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "S3_NO_FULL_PERMISSION"
]

# Checks there is no wildcard in the bucket name in an IAM Policy

rule BUCKET_POLICY_FULL_BUCKET_NAME_USED when %s3_no_full_permission !empty {
  let violationsString = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}


# Checks the full folder path is used with no wildcards before the second "/" in an IAM Policy

rule BUCKET_POLICY_FULL_FOLDER_PATH_USED when %s3_no_full_permission !empty {
  let violationsString = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::llp(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::llp(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

The commands you used to invoke the tool
        OUTPUT=RUST_BACKTRACE=1 ./cfn-guard-v3-ubuntu-latest/cfn-guard validate --show-summary pass,fail --data "$TEMPLATE_FILE" --rules .github/folderlib/cfn-guard/rules/ 2>&1 

The output of a -v log level if it's not related to cfn-guard-lambda, or the relevant CloudWatch log messages if it is related to the cfn-guard-lambda
s3_no_full_access.guard/IAM_ROLE_NO_FULL_ACCESS_FOR_S3      FAIL
---
Evaluating data template.yml against rules s3_no_full_access.guard
Number of non-compliant resources 1
Resource = rImmutaRdsLambdaRole {
  Type      = AWS::IAM::Role
  Rule = IAM_ROLE_NO_FULL_ACCESS_FOR_S3 {
    ALL {
      Check =  %violationsSub EMPTY   {
        ComparisonError {
          Message          {
            Violation: * in S3 folder (prefix) access.
            Fix: Avoid wildcard matching * in S3 folder (prefix) access
          }
          Error            = Check was not compliant as property [/Resources/rImmutaRdsLambdaRole[L:1549,C:4]] was not empty.
          PropertyPath    = /Resources/rImmutaRdsLambdaRole[L:1549,C:4]
          Operator        = EMPTY
          Code:
             1547.      Principal: secretsmanager.amazonaws.com
             1548.
             1549.  rImmutaRdsLambdaRole:
             1550.    Type: "AWS::IAM::Role"
             1551.    Properties:
             1552.      RoleName: !Sub immuta-rds-invoke-lambda-role-

        }
      }
    }
  }
}

Expected behavior
A clear and concise description of what you expected to happen.

The test should skip

Operating System:
[eg, MacOS, Windows, Ubuntu, etc]

Linux

OS Version
[eg Catalina, 10, 18.04, etc]

Ubuntu latest

@Aaron-Garrett Aaron-Garrett added the bug Something isn't working label Sep 16, 2024
@Aaron-Garrett
Copy link
Author

This is a duplicate of a previous issue, but I got too busy and forgot to check on it. The comment on that was that the rules did not appear to be in the Issue, but they were, hence my bold heading highlighting that as silly as it seems, the rules above are the ones that were failing.

@joshfried-aws
Copy link
Contributor

joshfried-aws commented Sep 17, 2024

Hi @Aaron-Garrett as mentioned in your previous issue, the rule from your provided output that fails is IAM_ROLE_NO_FULL_ACCESS_FOR_S3 the definition for this rule is not included in your snippet above. Without the definition of this rule, we aren't able to help you. I can see you're passing a directory (--rules .github/folderlib/cfn-guard/rules/), and not a single rule file, and it's not clear if your snippet includes all the rules in this directory or not (since we're missing the definition for the previously mentioned rule, I'm assuming not).

Again, this rule must be defined somewhere, so please provide it's definition so we can reproduce and help you.

For future reference, please re-open the previous issue instead of creating a new one.

Thanks,

@joshfried-aws
Copy link
Contributor

In addition to my above comment, to help you find it the output indicates the file this rule is defined in is s3_no_full_access.guard

@Aaron-Garrett
Copy link
Author

Aaron-Garrett commented Sep 27, 2024

Alright. I could not figure out how to reopen the issue. It is the correct rule, I have just updated the names since the error occurred in an attempt to bring more clarity to the output.

@joshfried-aws
Copy link
Contributor

Hi @Aaron-Garrett this above snippet still doesn't include the definition for the rule IAM_ROLE_NO_FULL_ACCESS_FOR_S3 I am unable to assist you without this rules definition.

@joshfried-aws
Copy link
Contributor

Hi @Aaron-Garrett I see you have edited your comment since my last reply. I want you to know I am unable to reproduce the issue (using cfn-guard v3.1.1) with everything you have provided.

> cfn-guard validate -r 567.guard -d 567.yaml -S all
/test-files/567.yaml Status = SKIP
SKIP rules
567.guard/IAM_ROLE_FULL_BUCKET_NAME_USED         SKIP
567.guard/IAM_ROLE_FULL_FOLDER_PATH_USED         SKIP
567.guard/IAM_POLICY_FULL_BUCKET_NAME_USED       SKIP
567.guard/IAM_POLICY_FULL_FOLDER_PATH_USED       SKIP
567.guard/BUCKET_POLICY_FULL_BUCKET_NAME_USED    SKIP
567.guard/BUCKET_POLICY_FULL_FOLDER_PATH_USED    SKIP
---
> cfn-guard --version
cfn-guard 3.1.1

@Aaron-Garrett
Copy link
Author

Aaron-Garrett commented Oct 17, 2024

Here is another one that just failed today. Here is the code in the CloudFormation template:

    rDMSPhysicianPolicyReadWrite:
      Type: "AWS::IAM::ManagedPolicy"
      Properties:
        ManagedPolicyName: "dms-physicianresearch-rw"
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            -
              Effect: Allow
              Action:
                - 'dms:ReloadTables'
                - 'dms:StopReplicationTask'
                - 'dms:StartReplicationTask'
                - 'dms:ModifyReplicationTask'
                - 'dms:ModifyEndpoint'
                - 'dms:TestConnection'
              Resource: 
                # - !Ref rLglPhysicianResearchReplicationTaskInfotrac
                # - !Ref rLglPhysicianResearchReplicationTaskTlac
                # - !Ref rLglPhysicianResearchReplicationTaskTlps
                # - !Ref rLglPhysicianResearchReplicationTaskUsol
                - !Ref rLglPhysicianResearchTargetEndpointInfotrac
                - !Ref rLglPhysicianResearchTargetEndpointTlac
                - !Ref rLglPhysicianResearchTargetEndpointTlps
                - !Ref rLglPhysicianResearchTargetEndpointUsol
                - !Ref rLglPhysicianResearchsourcepointInfotrac
                - !Ref rLglPhysicianResearchsourcepointTlac
                - !Ref rLglPhysicianResearchsourcepointTlps
                - !Ref rLglPhysicianResearchsourcepointUsol

        Roles:                                                            
          -  !Sub ${pBusinessUsecase}_data_processing_role
          -  !If [ CreateDevResources,!Sub "aws_${pBusinessUsecase}_developers", !Ref "AWS::NoValue" ]
          #- !Sub arn:aws:iam::${AWS::AccountId}:role/aws_${pBusinessUsecase}_developers

Here is the error from CFN-Guard:

Evaluating data TEMPLATE.yml against rules s3_full_path_used.guard
Number of non-compliant resources 2
Resource = rDMSPhysicianPolicyReadWrite {
  Type      = AWS::IAM::ManagedPolicy
  Rule = IAM_POLICY_FULL_BUCKET_NAME_USED {
    ALL {
      Check =  %violationsSub EMPTY   {
        ComparisonError {
          Message          {
            Violation: * in S3 folder (prefix) access.
            Fix: Avoid wildcard matching * in S3 folder (prefix) access
          }
          Error            = Check was not compliant as property [/Resources/rDMSPhysicianPolicyReadWrite[L:734,C:6]] was not empty.
          PropertyPath    = /Resources/rDMSPhysicianPolicyReadWrite[L:734,C:6]
          Operator        = EMPTY
          Code:
              732.              - '"'
              733.              - '}' 
              734.    rDMSPhysicianPolicyReadWrite:
              735.      Type: "AWS::IAM::ManagedPolicy"
              736.      Properties:
              737.        ManagedPolicyName: "dms-physicianresearch-rw"

        }
      }
    }
  }
  Rule = IAM_POLICY_FULL_FOLDER_PATH_USED {
    ALL {
      Check =  %violationsSub EMPTY   {
        ComparisonError {
          Message          {
            Violation: * in S3 folder (prefix) access.
            Fix: Avoid wildcard matching * in S3 folder (prefix) access
          }
          Error            = Check was not compliant as property [/Resources/rDMSPhysicianPolicyReadWrite[L:734,C:6]] was not empty.
          PropertyPath    = /Resources/rDMSPhysicianPolicyReadWrite[L:734,C:6]
          Operator        = EMPTY
          Code:
              732.              - '"'
              733.              - '}' 
              734.    rDMSPhysicianPolicyReadWrite:
              735.      Type: "AWS::IAM::ManagedPolicy"
              736.      Properties:
              737.        ManagedPolicyName: "dms-physicianresearch-rw"

        }
      }
    }
  }
}

And here is the CloudFormation guard script:

# R5.0  Automatically inspect the code for * in S3 folder (prefix) access and present a warning statement to the developer if found

let aws_iam_policies_no_full_access_for_s3 = Resources.*[
  Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "IAM_POLICY_NO_FULL_ACCESS_FOR_S3"
]

let aws_iam_roles_no_full_access_for_s3 = Resources.*[
  Type in [/AWS::IAM::Role/]
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "IAM_ROLE_NO_FULL_ACCESS_FOR_S3"
]

# Checks there is no wildcard in the bucket name in an IAM Role

rule IAM_ROLE_FULL_BUCKET_NAME_USED when %aws_iam_roles_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks the full folder path is used with no wildcards before the second "/" in an IAM Role

rule IAM_ROLE_FULL_FOLDER_PATH_USED when %aws_iam_roles_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks there is no wildcard in the bucket name in an IAM Policy

rule IAM_POLICY_FULL_BUCKET_NAME_USED when %aws_iam_policies_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

# Checks the full folder path is used with no wildcards before the second "/" in an IAM Policy

rule IAM_POLICY_FULL_FOLDER_PATH_USED when %aws_iam_policies_no_full_access_for_s3 !empty {
  let violationsString = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Policy/, /AWS::IAM::ManagedPolicy/]
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

let s3_no_full_permission = Resources.*[ Type == 'AWS::S3::BucketPolicy'
  Metadata.guard.SuppressedRules not exists or
  Metadata.guard.SuppressedRules.* != "S3_NO_FULL_PERMISSION"
]

# Checks there is no wildcard in the bucket name in an IAM Policy

rule BUCKET_POLICY_FULL_BUCKET_NAME_USED when %s3_no_full_permission !empty {
  let violationsString = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  let violationsSub = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}


# Checks the full folder path is used with no wildcards before the second "/" in an IAM Policy

rule BUCKET_POLICY_FULL_FOLDER_PATH_USED when %s3_no_full_permission !empty {
  let violationsString = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  let violationsSub = Resources.*[
    Type == 'AWS::S3::BucketPolicy'
    some Properties.PolicyDocument.Statement[*] {
      some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::lly-(.*?)(\*)(.*?)\/(.*?)\/(.*?)/, /^arn:aws:s3:::lly-(.*?)\/(.*?)(\*)(.*?)\/(.*)/]
    }
  ]
  %violationsString empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
  %violationsSub empty
  <<
    Violation: * in S3 folder (prefix) access.
    Fix: Avoid wildcard matching * in S3 folder (prefix) access
  >>
}

It seems to keep happening on DMS permissions. No idea why.

@Aaron-Garrett
Copy link
Author

Following up to see if there's any update.

@Aaron-Garrett
Copy link
Author

Following up again as I keep running into this issue and it is causing some issues in my use case.

@joshfried-aws
Copy link
Contributor

Hey @Aaron-Garrett sorry about the delay here.

The issue with your rules is the way youre writing them. This can be seen with a verbose flag being added to your rules.

when you write a check like this

  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
    some Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]

what youre doing is essentially querying for a type map filter, and youre and-ing it with the keys map filter, when your keys is not present this is skipped so youre getting true AND skip which results to a true.

You have 2 options to re-write this check and all of them that are like this

  let violationsSub = Resources.*[
    Type in [/AWS::IAM::Role/]
    some Properties.Policies[*].PolicyDocument.Statement[*] {
      Resource[*]["Fn::Sub"] exists
      Resource[*][keys == "Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
    }
  ]

or

  let violationsSub = Resources.*[
  Type in [/AWS::IAM::Role/]
  some Properties.Policies[*].PolicyDocument.Statement[*] {
    Resource[*]["Fn::Sub"] in [/^arn:aws:s3:::(.*?)(.*?)(\*)(.*?)\/$/]
  }
]

note the difference between using the second option and what you had is in the second option youre not applying a map filter, youre doing a direct access query (like a key in a dictionary/hashmap). When using an access query, this results in a falsey value if the key DNE.

Please let me know if that solves any/all issues youre having here.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants