bridgecrewio / checkov

Prevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.
https://www.checkov.io/
Apache License 2.0
6.72k stars 1.08k forks source link

Filter working as intended? #6355

Closed dishikang123 closed 2 weeks ago

dishikang123 commented 1 month ago

Describe the issue I am trying to create custom checks in YAML to validate against cloudformation templates. In trying to use filter to filter out resources where the rule is applicable, it doesn't seem to be working. The resource in question is AWS::RDS::DBParameterGroup and I only want to validate the rule when Family is postgres 13 - 15. The rule I came with up works fine against postgres, but still flags other family such as mysql as failure when it should be skipped.

Example Value Input:

 Postgres15StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for Postgres 15
      Family: postgres15
      Parameters:
        ssl_min_protocol_version: TLSv1.2
  MySQL8StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for MySQL 8
      Family: mysql8.0
      Parameters:        
        require_secure_transport: 1

rule:

metadata:
  id: "TEST_AWS_1"
  name: "Ensure RDS PostgreSQL parameters are configured"
  category: "GENERAL_SECURITY"
definition:
  and:
    - cond_type: "filter"
      resource_types:
      - "AWS::RDS::DBParameterGroup"
      attribute: Family
      operator: within
      value: 
        - "postgres13"
        - "postgres14"
        - "postgres15"
    - cond_type: "attribute"
      resource_types:
      - "AWS::RDS::DBParameterGroup"
      attribute: Parameters.ssl_min_protocol_version
      operator: equals
      value: "TLSv1.2"
maxamel commented 4 weeks ago

Can you please post your checkov command? And the report output (passed/failed checks) ?

dishikang123 commented 4 weeks ago

@maxamel

command: .\checkov.exe -f <path to file> --external-checks-dir <path to custom checks> -c TEST*

output:

   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V / 
  \___|_| |_|\___|\___|_|\_\___/ \_/  

By Prisma Cloud | version: 3.2.94 

cloudformation scan results:

Passed checks: 3, Failed checks: 1, Skipped checks: 0

Check: TEST_AWS_4: "Ensure RDS PostgreSQL parameters are configured according to requirements"
    PASSED for resource: AWS::RDS::DBParameterGroup.Postgres13StandardParameterGroup
    File: /..\..\rdsparameters.yml:108-131
Check: TEST_AWS_4: "Ensure RDS PostgreSQL parameters are configured according to requirements"
    PASSED for resource: AWS::RDS::DBParameterGroup.Postgres14StandardParameterGroup
    File: /..\..\rdsparameters.yml:149-172
Check: TEST_AWS_4: "Ensure RDS PostgreSQL parameters are configured according to requirements"
    PASSED for resource: AWS::RDS::DBParameterGroup.Postgres15StandardParameterGroup
    File: /..\..\rdsparameters.yml:191-214
Check: TEST_AWS_4: "Ensure RDS PostgreSQL parameters are configured according to requirements"
    FAILED for resource: AWS::RDS::DBParameterGroup.MySQL8StandardParameterGroup
    File: /..\..\rdsparameters.yml:26-50

        26 |   MySQL8StandardParameterGroup:
        27 |     Type: AWS::RDS::DBParameterGroup
        28 |     Properties:
        29 |       Description: Standard Parameter Group for MySQL 8
        30 |       Family: mysql8.0
        31 |       Parameters:        
        32 |         require_secure_transport: 1
        33 |         tls_version: TLSv1.2
        34 |         local_infile: 0
        35 |         general_log: 1
        36 |         log_output: FILE
        37 |         slow_query_log: 1
        38 |         max_user_connections: 10
        39 |         password_history: 24
        40 |         password_reuse_interval: 365
        41 |         validate_password_length: 12
        42 |         validate_password_mixed_case_count: 1
        43 |         validate_password_number_count: 1
        44 |         validate_password_policy: STRONG
        45 |         validate_password_special_char_count: 1
        46 |         default_password_lifetime: 365
        47 |         log_error_verbosity: 2
        48 |         sql_mode: STRICT_ALL_TABLES
        49 |         master-info-repository: TABLE
        50 |         performance_schema: 1
maxamel commented 3 weeks ago

Currently this cannot be reproduced. Judging from the report output it seems the input file is different than the one mentioned in the issue description. Can you attach the full rdsparameters.yml ?

dishikang123 commented 3 weeks ago
AWSTemplateFormatVersion: "2010-09-09"
Description: Standardized RDS configurations, such as Parameter Groups and Option Groups for specific database versions

Resources:  
  MySQL8StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for MySQL 8
      Family: mysql8.0
      Parameters:        
        require_secure_transport: 1
        tls_version: TLSv1.2
        local_infile: 0
        general_log: 1
        log_output: FILE
        slow_query_log: 1
        max_user_connections: 10
        password_history: 24
        password_reuse_interval: 365
        validate_password_length: 12
        validate_password_mixed_case_count: 1
        validate_password_number_count: 1
        validate_password_policy: STRONG
        validate_password_special_char_count: 1
        default_password_lifetime: 365
        log_error_verbosity: 2
        sql_mode: STRICT_ALL_TABLES
        master-info-repository: TABLE
        performance_schema: 1

  Postgres13StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for Postgres 13
      Family: postgres13
      Parameters:
        rds.force_ssl: 1
        ssl_min_protocol_version: TLSv1.2

  Postgres14StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for Postgres 14
      Family: postgres14
      Parameters:
        rds.force_ssl: 1
        ssl_min_protocol_version: TLSv1.2

  Postgres15StandardParameterGroup:
    Type: AWS::RDS::DBParameterGroup
    Properties:
      Description: Standard Parameter Group for Postgres 15
      Family: postgres15
      Parameters:
        rds.force_ssl: 1
        ssl_min_protocol_version: TLSv1.2
maxamel commented 2 weeks ago

I managed to reproduce this issue. @tsmithv11 the docs state filter is most commonly used with connection blocks, and I haven't seen explicit examples similar to the one above. It does seem like this case should work, what do you think?

tsmithv11 commented 2 weeks ago

Thank you for reporting, @dishikang123 and thanks for investigating, @maxamel.

I believe we built the filter to only work for resource types not based on attributes in a resource block. This is an interesting idea to refine a policy so it doesn't flag (good or bad) specific resources, but not currently supported. For now, you can use:

definition:
  or:
    - cond_type: "attribute"
      resource_types:
      - "AWS::RDS::DBParameterGroup"
      attribute: Family
      operator: not_within
      value: 
        - "postgres13"
        - "postgres14"
        - "postgres15"
    - cond_type: "attribute"
      resource_types:
      - "AWS::RDS::DBParameterGroup"
      attribute: Parameters.ssl_min_protocol_version
      operator: equals
      value: "TLSv1.2"

It will show the first resource block as passing which can be "noisy" but at least it's not a false positive.

dishikang123 commented 2 weeks ago

@tsmithv11 Thanks for the suggestion. If I understand the logic correctly, both attributes get evaluated first and have the or applied, as opposed to if first attribute evaluated to true, then the second attribute will not get evaluated at all.

tsmithv11 commented 2 weeks ago

@dishikang123 correct