Giter VIP home page Giter VIP logo

skyscanner / cfripper Goto Github PK

View Code? Open in Web Editor NEW
389.0 14.0 53.0 1.14 MB

Library and CLI tool for analysing CloudFormation templates and check them for security compliance.

Home Page: https://cfripper.readthedocs.io/

License: Apache License 2.0

Makefile 0.35% Python 99.65%
cfripper cloudformation-template cloudformation cloud-governance cloudformation-linter aws-security static-analysis compliance aws

cfripper's People

Contributors

alisonatwork avatar carleslopez avatar cogpie avatar dependabot[bot] avatar ignaciobolonio avatar ignaciorv avatar jsoucheiron avatar karl-jurvanen avatar lpmi-13 avatar marcsantamaria-sky avatar max-huneshagen avatar morrolan avatar mretallack avatar nafpliot avatar ocrawford555 avatar oscarbc96 avatar patmyron avatar rpinuaga-sky avatar w0rmr1d3r avatar xavi-bean avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cfripper's Issues

CFRipper fails to run `make test` on Python 3.10

When running make install-dev and make test on a fresh Python 3.10 virtual environment, the following error is encountered:

 $ make test
isort --check-only --recursive cfripper tests docs setup.py
black --check cfripper tests docs setup.py
All done! ✨ 🍰 ✨
103 files would be left unchanged.
flake8 cfripper tests docs setup.py
pytest -svvv tests
============================================================================================== test session starts ==============================================================================================
platform darwin -- Python 3.10.1, pytest-7.1.1, pluggy-0.13.1 -- /Users/olivercrawford/projects/cfripper_public/cfripper/venv/bin/python3.10
cachedir: .pytest_cache
rootdir: /Users/olivercrawford/projects/cfripper_public/cfripper
plugins: cov-3.0.0
collected 565 items / 1 error

==================================================================================================== ERRORS =====================================================================================================
__________________________________________________________________________________ ERROR collecting tests/test_boto3_client.py __________________________________________________________________________________
tests/test_boto3_client.py:7: in <module>
    from moto import mock_cloudformation, mock_s3, mock_sts
venv/lib/python3.10/site-packages/moto/__init__.py:9: in <module>
    from .cloudformation import mock_cloudformation  # noqa
venv/lib/python3.10/site-packages/moto/cloudformation/__init__.py:2: in <module>
    from .models import cloudformation_backends
venv/lib/python3.10/site-packages/moto/cloudformation/models.py:11: in <module>
    from .parsing import ResourceMap, OutputMap
venv/lib/python3.10/site-packages/moto/cloudformation/parsing.py:407: in <module>
    class ResourceMap(collections.Mapping):
E   AttributeError: module 'collections' has no attribute 'Mapping'
=============================================================================================== warnings summary ================================================================================================
venv/lib/python3.10/site-packages/boto/plugin.py:40
  /Users/olivercrawford/projects/cfripper_public/cfripper/venv/lib/python3.10/site-packages/boto/plugin.py:40: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
    import imp

venv/lib/python3.10/site-packages/docker/credentials/utils.py:1
  /Users/olivercrawford/projects/cfripper_public/cfripper/venv/lib/python3.10/site-packages/docker/credentials/utils.py:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
    import distutils.spawn

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
============================================================================================ short test summary info ============================================================================================
ERROR tests/test_boto3_client.py - AttributeError: module 'collections' has no attribute 'Mapping'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================================================================= 2 warnings, 1 error in 3.77s ==========================================================================================
make: *** [unit] Error 2

Looks like the moto library will need updating to > 3.0.0 to support Python 3.10.

JUnitXML output support

Hi,

Are there any plans to support junitxml output support? This would make it easier to integrate into CI/CD pipelines with reports and metrics.

Thanks

Tool fails to parse template with KMS Key Policies that have function based statement

If I have a template that contains a KeyPolicy that contains a function based statement I receive a set of Attribute Errors from the tool even though it is a valid cloud formation template. I would expect this to be parsable

Discovered while using version 1.0.7

Template:

  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "The AWS CloudFormation template for this Serverless application",
  "Resources": {
    "CustomerMasterKey": {
      "Type": "AWS::KMS::Key",
      "Properties": {
        "Description": "customerKey",
        "Enabled": true,
        "EnableKeyRotation": true,
        "KeyPolicy": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": "arn:aws:iam::0123456789:root"
              },
              "Action": "kms:*",
              "Resource": "*"
            },
            {
              "Fn::If": [
                "IsRightRole",
                {
                  "Sid": "Allow role to use key",
                  "Effect": "Allow",
                  "Principal": {
                    "AWS": {
                      "Fn::ImportValue": "RoleArn"
                    }
                  },
                  "Action": [
                    "kms:Decrypt",
                    "kms:GenerateDataKey"
                  ],
                  "Resource": "*"
                },
                {
                  "Ref": "AWS::NoValue"
                }
              ]
            }
          ]
        },
        "KeyUsage": "ENCRYPT_DECRYPT",
        "PendingWindowInDays": 7,
        "Tags": []
      }
    }
  },
  "Conditions": {
    "IsRightRole": {
      "Fn::Or": [
        {
          "Fn::Equals": [
            "wrong",
            "right"
          ]
        },
        {
          "Fn::Equals": [
            "right",
            "right"
          ]
        }
      ]
    }
  }
}

cfripper output:

~cfripper ~/tmp/template.json
Analysing ~/tmp/template.json...
Not adding KMSKeyCrossAccountTrustRule failure in CustomerMasterKey because no AWS Account ID was found in the config.
KMSKeyCrossAccountTrustRule crashed with AttributeError for project - None, service - None, stack - None
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/cfripper/rule_processor.py", line 24, in process_cf_template
    result += rule.invoke(cfmodel, extras)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/cross_account_trust.py", line 59, in invoke
    self._do_statement_check(result, logical_id, statement, filters_available_context)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/cross_account_trust.py", line 65, in _do_statement_check
    if statement.Effect == "Allow":
AttributeError: 'FunctionDict' object has no attribute 'Effect'
KMSKeyWildcardPrincipalRule crashed with AttributeError for project - None, service - None, stack - None
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/cfripper/rule_processor.py", line 24, in process_cf_template
    result += rule.invoke(cfmodel, extras)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/kms_key_wildcard_principal.py", line 41, in invoke
    if statement.Effect == "Allow" and statement.principals_with(self.CONTAINS_WILDCARD_PATTERN):
AttributeError: 'FunctionDict' object has no attribute 'Effect'
WildcardResourceRule crashed with AttributeError for project - None, service - None, stack - None
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/cfripper/rule_processor.py", line 24, in process_cf_template
    result += rule.invoke(cfmodel, extras)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/base_rules.py", line 104, in invoke
    result += self.resource_invoke(resource=resource, logical_id=logical_id, extras=extras)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/wildcard_resource_rule.py", line 58, in resource_invoke
    self._check_policy_document(result, logical_id, resource.Properties.KeyPolicy, None, extras)
  File "/usr/local/lib/python3.9/site-packages/cfripper/rules/wildcard_resource_rule.py", line 70, in _check_policy_document
    for statement in policy_document.statements_with(REGEX_IS_STAR):
  File "/usr/local/lib/python3.9/site-packages/pycfmodel/model/resources/properties/policy_document.py", line 42, in statements_with
    return [statement for statement in self._statement_as_list() if statement.resources_with(pattern)]
  File "/usr/local/lib/python3.9/site-packages/pycfmodel/model/resources/properties/policy_document.py", line 42, in <listcomp>
    return [statement for statement in self._statement_as_list() if statement.resources_with(pattern)]
AttributeError: 'FunctionDict' object has no attribute 'resources_with'

Support using it as library? (PyPi package seems broken)

I'm trying to call cfripper from a Python script and looks like that can't be done yet.
I installed cfripper from PyPI and it doesn't seem to have all the necessary files, e.g The rule_processor.py script is missing. So we can't use the RuleProcessor class yet unless we are using the lambda package and not the PyPI one. See screenshot.

image

I think it's because the package isn't recursively copying all files as the directories, i.e config, model and rules are missing.

Installation problem

Hey guys, I have a problem with the lambda installation that you might be able to help me with.

I ran the make lambda.zip but I cannot seem to define the correct entrypoint / handler (?) in AWS. I have defined cfripper.main.handler but I get Unable to import module 'cfripper.main'.

A more detailed output of the error is Unable to import module 'cfripper.main': No module named 'dataclasses', but after installing dataclasses I get module initialization error: issubclass() arg 1 must be a class.

Maybe I am missing something but since there is no installation documentation I don't know what I am doing wrong.

TypeError: unhashable type: 'FunctionDict'

Hi, we are trialing cfripper as part of our ci pipeline, and it feels awesome, but I have encountered a few places where it seems cfmodel fails to understand the structures, causing cfripper to fail with an exception. Most recent one, a real blocker for us, is issue with s3 bucket + policy, when policy contains s3:ListBucket.

Here's a minimal example that fails:

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: "my-test-bucket"
  TestBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref "TestBucket"
      PolicyDocument:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": ["s3:ListBucket"],
              "Effect": "Allow",
              "Resource": !GetAtt TestBucket.Arn,
              "Principal": {
                  "AWS": "aws:arn:aws:iam::00000000:user/Dave"
              }
            }
          ]
        }

When running with cfripper 0.18.1, we get:

cfripper cfripper_test.yaml
Analysing cfripper_test.yaml...
Condition=None Statement=[Statement(Condition=None, Sid=None, Effect='Allow', Principal={'AWS': 'aws:arn:aws:iam::00000000:user/Dave'}, NotPrincipal=None, Action=['s3:ListBucket'], NotAction=None, Resource=FunctionDict(Fn::GetAtt=['TestBucket', 'Arn']), NotResource=None)] Version=datetime.date(2012, 10, 17)
S3BucketPublicReadAclAndListStatementRule crashed with TypeError for project - None, service - None, stack - None
Traceback (most recent call last):
File "/home/arto/.local/lib/python3.8/site-packages/cfripper/rule_processor.py", line 22, in process_cf_template
result += rule.invoke(cfmodel, extras)
File "/home/arto/.local/lib/python3.8/site-packages/cfripper/rules/s3_public_access.py", line 40, in invoke
bucket = cfmodel.Resources.get(bucket_name)
TypeError: unhashable type: 'FunctionDict'

If I replace in Bucket Policy the bucket Ref by hardcoded bucket name, like this, then it works:

Resources:
  TestBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: "my-test-bucket"
  TestBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: "my-test-bucket"
      PolicyDocument:
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": ["s3:ListBucket"],
              "Effect": "Allow",
              "Resource": !GetAtt TestBucket.Arn,
              "Principal": {
                  "AWS": "aws:arn:aws:iam::00000000:user/Dave"
              }
            }
          ]
        }

I've seen at least one similar thing in the past, with cfmodel, but there was a workaround for it then, that made sense.

You can simplify this farther, but I think that bucket ref should be valid in Cloudformation, but it's not accepted by cfmodel, when using s3:ListBucket policy. Oddly enough, when we use s3:GetObject or other object level policies, they work without exception.

Any ideas on what this might be? Right now our workaround would be to hardcode the bucket name, instead of using a ref, but it's slightly silly workaround.

AWS S3 path format issue

While trying to test the tool we ran into an issue with S3 bucket path failing to be recognized. The utils.py file has five tests for different ways of accessing S3 objects, but after creating a new bucket for the json object, the path was not recognized.

S3 link: https://BUCKETNAME.s3.REGION.amazonaws.com/test.json

We simply used a supported format to make this work, but it would better if the above S3 path format was recognized out of the box.

Unhandled exception when template file is empty

Hi,

I found a minor issue when running cfripper with a list of files. I had a blank file in that list and there was an exception. The exception helped to understand something was wrong but it would be good if cfripper check the validity of the CF file first before throwing an exception.

Please find the steps to reproduce below:

Steps to reproduce:

Create a blank file:

touch example.yml

Execute cfripper:

cfripper example.yml

Exception is raised:

Analysing example.yml...
Unhandled exception raised, please create an issue wit the error message at https://github.com/Skyscanner/cfripper/issues
Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/cfripper/cli.py", line 151, in cli
    process_template(template=template, resolve_parameters=resolve_parameters, **kwargs)
  File "/usr/lib/python3.8/site-packages/cfripper/cli.py", line 90, in process_template
    cfmodel = get_cfmodel(template)
  File "/usr/lib/python3.8/site-packages/cfripper/cli.py", line 39, in get_cfmodel
    cfmodel = pycfmodel.parse(template)
  File "/usr/lib/python3.8/site-packages/pycfmodel/__init__.py", line 19, in parse
    return CFModel(**template)
TypeError: ModelMetaclass object argument after ** must be a mapping, not NoneType

I think it should be great if cfripper handles the error outputting a message like:

Analysing example.yml...
example.yml is not a valid template.

Thanks!

CLIification?

Hi,

Wondering if there are any plans to turn this into a plain CLI tool for integrating into, e.g., CI/CD pipelines.

Validation errors for CFModel

I tried cfripper against an template which had below two parameters:

Transform: AWS::Serverless-2016-10-31
Globals:
  Function:
    Runtime: python3.7
    MemorySize: 256
    Timeout: 5

I get the below error :

Unhandled exception raised, please create an issue wit the error message at https://github.com/Skyscanner/cfripper/issues
Traceback (most recent call last):
  File "/private/var/folders/x3/_68l07kx74q32x0msgcs07t9md8s2c/T/tmp3as4xqx8/multiaccount/.venv/lib/python3.7/site-packages/cfripper/cli.py", line 150, in cli
    process_template(template=template, resolve_parameters=resolve_parameters, **kwargs)
  File "/private/var/folders/x3/_68l07kx74q32x0msgcs07t9md8s2c/T/tmp3as4xqx8/multiaccount/.venv/lib/python3.7/site-packages/cfripper/cli.py", line 89, in process_template
    cfmodel = get_cfmodel(template)
  File "/private/var/folders/x3/_68l07kx74q32x0msgcs07t9md8s2c/T/tmp3as4xqx8/multiaccount/.venv/lib/python3.7/site-packages/cfripper/cli.py", line 38, in get_cfmodel
    cfmodel = pycfmodel.parse(template)
  File "/private/var/folders/x3/_68l07kx74q32x0msgcs07t9md8s2c/T/tmp3as4xqx8/multiaccount/.venv/lib/python3.7/site-packages/pycfmodel/__init__.py", line 5, in parse
    return CFModel(**template)
  File "/private/var/folders/x3/_68l07kx74q32x0msgcs07t9md8s2c/T/tmp3as4xqx8/multiaccount/.venv/lib/python3.7/site-packages/pydantic/main.py", line 283, in __init__
    raise validation_error
pydantic.error_wrappers.ValidationError: 2 validation errors for CFModel
Transform
  value is not a valid list (type=type_error.list)
Globals
  extra fields not permitted (type=value_error.extra)

False positive for missing egress rules

CFRipper version 0.22.0 gives a false positive for missing egress rules.

It happens when the rule is defined as a SecurityGroupEgress resource.

Consider the following test1.yml template. It creates security group with no egress using a SecurityGroupEgress resource.

---
AWSTemplateFormatVersion: 2010-09-09
Description: Security Group without egress

Resources:

  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub "${AWS::StackName}" 
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}"

  EC2SGEgress:
    Type: AWS::EC2::SecurityGroupEgress
    Properties:
      GroupId: !GetAtt EC2SG.GroupId
      Description: Localhost only. CFN hack to forbid egress
      IpProtocol: "-1"
      CidrIp: 127.0.0.1/32

The result is invalid for test1.yml:

$ cfripper test1.yml
Analysing test.yml...
Valid: False
Issues found:
	- EC2SecurityGroupMissingEgressRule: Missing egress rule in EC2SG means all traffic is allowed outbound. Make this explicit if it is desired configuration

Now consider the following test2.yml template. It also crease a security group with no egress, this time using the SecurityGroupEgress proprty of the SecurityGroup resource.

---
AWSTemplateFormatVersion: 2010-09-09
Description: Security Group without egress

Resources:

  EC2SG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub "${AWS::StackName}"
      SecurityGroupEgress:
       - IpProtocol: -1
         CidrIp: 127.0.0.1/32
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}"

The result is valid for test2.yml:

$ cfripper test2.yml
Analysing test.yml...
Valid: True

The result should be valid for both ways of writing this.

(I found the following Stack Overflow discussion useful while researching this.)

Installation Help

Hey, I was wondering if you might be able to provide clearer instructions on how to deploy this to AWS Lambda as that is not clearly covered in your readme. Unless I am missing something really obvious. #

CLI should return non-zero when stack is invalid

I'm setting up a quick demo infrastructure that includes an RDS instance. I hardcode the master password for my database because it's the easiest thing to do.

  RDSInstance:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: !Ref DBInstanceIdentifier
      DBInstanceClass: db.t3.micro
      Engine: mysql
      EngineVersion: 8.0.21
      DBSubnetGroupName: !Ref DBSubnetGroup
      PubliclyAccessible: false
      StorageEncrypted: true
      AllocatedStorage: "20"
      MasterUsername: root
      MasterUserPassword: password

CFRipper correctly calls me out on that and declares the stack invalid from a security perspective. Great!

$ cfripper stack.yml
Analysing stack.yml...
Valid: False
Issues found:
	- HardcodedRDSPasswordRule: RDS Instance password parameter missing NoEcho for RDSInstance.
$ echo $?
0

However, as you can see, the exit code is still 0.

That means this doesn't automatically trigger a failure in my CI system.

I was expecting to see a 1 or something else falsy.

I'm using Bitbucket Pipelines which passes each step if the exit code is 0 and fails otherwise. I believe most other CI systems work the same way.

Because this looks like a pass to Bitbucket Pipelines, I have to remember to inspect the output every time I want to know if there's a potential security issue.

So could we have CFRipper return a non-zero exit code when the stack is found to be invalid?

It could just be as simple as 0 for valid and 1 for invalid without any more detail.

The other tools in my pipeline work in a similar way, although they are more complex or nuanced that what is porbably needed in CFRipper.

  • cfn_nag

    • A failing violation will return a non-zero exit code.
    • A warning will return a zero/success exit code.
  • cfn-lint

    • 0 is no issue was found
    • 2 is an error
    • 4 is a warning
    • 6 is an error and a warning
    • 8 is an informational
    • 10 is an error and informational
    • 12 is an warning and informational
    • 14 is an error and a warning and an informational

StackNameMatchesRegexRule crashed with AttributeError

Hi guys

cfripper, version 1.15.1

I was just testing the filter rule option and taking the example from the readme I'm getting an exception

# cfripper cfripper/tests/test_templates/config/security_group_firehose_ips.json --rules-filters-folder cfripper/cfripper/config/rule_configs

StackNameMatchesRegexRule crashed with AttributeError for project - None, service - None, stack - None
Traceback (most recent call last):
  File "/Users/rubenortiz/Projects/Ruben/Deploybot/venv/lib/python3.9/site-packages/cfripper/rule_processor.py", line 24, in process_cf_template
    result += rule.invoke(cfmodel, extras)
  File "/Users/rubenortiz/Projects/Ruben/Deploybot/venv/lib/python3.9/site-packages/cfripper/rules/stack_name_matches_regex.py", line 31, in invoke
    stack_name = self._config.stack_name or extras.get("stack_name", "")
AttributeError: 'NoneType' object has no attribute 'get'
Valid: False
Issues found:
	- EC2SecurityGroupMissingEgressRule: Missing egress rule in RedshiftSecurityGroup means all traffic is allowed outbound. Make this explicit if it is desired configuration

Expected behavior: Valid True

Also I think I'm missing something in the command line, how can I pass the filter I want to test to the command?

Thanks

Could not parse JSON template

Could not parse JSON template
Traceback (most recent call last):
File "/opt/Skyscanner/cfripper/cfripper/model/utils.py", line 74, in convert_json_or_yaml_to_dict
file_content = to_json(file_content)
File "/usr/local/lib/python3.8/dist-packages/cfn_flip/init.py", line 55, in to_json
data, _ = load(template)
File "/usr/local/lib/python3.8/dist-packages/cfn_flip/init.py", line 34, in load
raise e
File "/usr/local/lib/python3.8/dist-packages/cfn_flip/init.py", line 27, in load
data = load_json(template)
File "/usr/local/lib/python3.8/dist-packages/cfn_tools/init.py", line 20, in load_json
return json.loads(source, object_pairs_hook=ODict)
File "/usr/lib/python3.8/json/init.py", line 370, in loads
return cls(**kw).decode(s)
File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Unhandled exception raised, please create an issue wit the error message at https://github.com/Skyscanner/cfripper/issues
Traceback (most recent call last):
File "/opt/Skyscanner/cfripper/cfripper/cli.py", line 150, in cli
process_template(template=template, resolve_parameters=resolve_parameters, **kwargs)
File "/opt/Skyscanner/cfripper/cfripper/cli.py", line 89, in process_template
cfmodel = get_cfmodel(template)
File "/opt/Skyscanner/cfripper/cfripper/cli.py", line 38, in get_cfmodel
cfmodel = pycfmodel.parse(template)
File "/usr/local/lib/python3.8/dist-packages/pycfmodel/init.py", line 5, in parse
return CFModel(**template)
TypeError: ModelMetaclass object argument after ** must be a mapping, not NoneType

AttributeError: 'NoneType' object has no attribute 'split' when using CommaDelimitedList

Tested with versions: 0.18, 0.19

When I create very simple cf yaml template like this:

AWSTemplateFormatVersion: "2010-09-09"
Parameters:
  SubnetIds:
    Type: CommaDelimitedList
    Description: Select at least two subnets in your selected VPC.

And run it like this:

cfripper test.yaml --resolve

It fails with:

Analysing test.yaml...
Unhandled exception raised, please create an issue wit the error message at https://github.com/Skyscanner/cfripper/issues
Traceback (most recent call last):
  File "/home/arto/.local/lib/python3.8/site-packages/cfripper/cli.py", line 150, in cli
    process_template(template=template, resolve_parameters=resolve_parameters, **kwargs)
  File "/home/arto/.local/lib/python3.8/site-packages/cfripper/cli.py", line 91, in process_template
    cfmodel = cfmodel.resolve(resolve_parameters)
  File "/home/arto/.local/lib/python3.8/site-packages/pycfmodel/model/cf_model.py", line 72, in resolve
    ref_value = parameter.get_ref_value(passed_value)
  File "/home/arto/.local/lib/python3.8/site-packages/pycfmodel/model/parameter.py", line 52, in get_ref_value
    return value.split(",")
AttributeError: 'NoneType' object has no attribute 'split'

Some other observations:

  • It passes of course without --resolve flag
  • With --resolve-parameters it probably succeeds. However, I did not try creating parameter file because we are trying to use this as quality gate step for templates without specifying custom parameter values for them. Not sure if this is supported, or if in this case parameters must be used.
  • With default parameter values it of course works, not willing to define placeholders just for sake of validation build step though

So it seems to me that would be great to have CommaDelimitedList type recognize when it does not have default or assigned value, and either use a build-in value, or at least not try to split it. I cannot say if this is a bug in --resolve functionality, or working as intended, but wanted to bring out this observation. We have been working around this by not using --resolve flag, then we of course don't get any exceptions from this.

Method add_warning of Result class has different behavior than add_failure

Description

Currently add_failure takes the values required to create a failure, creates it then adds it to the Result object's failed_rules
On the other hand add_warning takes a Failure object directly.

Proposed solution

The methods should be updated so that they both have the same behavior (or maybe even just add an add_finding method which takes a type that can be either Failure or Warrning 😄 )

Support for pycfmodel>=0.13.0

#203 started to pin pycfmodel to 0.13.0. This is an issue for distributions which are shipping cfripper as pycfmodel could be already at 0.16.0 and most distribution can't have multiple releases of the same pycfmodel package.

Are there any plan to support pycfmodel >=0.13.0?

Thanks

Error when the template contains Globals

Hi

Cfripper version: cfripper, version 1.15.1
Installed via: pip

congrats on your fantastic tool.

I'm just playing around a little bit. So far, I've checked two YAML files and I found out that one of them is crashing unexpectedly. But your message is pretty clear about it:

Unhandled exception raised, please create an issue with the error message at https://github.com/Skyscanner/cfripper/issues
Traceback (most recent call last):
    return CFModel(**template)
  File "pydantic/main.py", line 341, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for CFModel
Globals
  extra fields not permitted (type=value_error.extra)

Is there any reason you decided to don't take into account Globals? I'm just curious about it!

Thanks!

Error while parsing template with pycfmodel

Hi guys. I get the following error when I ran the lambda

[ERROR] TypeError: ModelMetaclass object argument after ** must be a mapping, not str
Traceback (most recent call last):
  File "/var/task/cfripper/main.py", line 119, in handler
    cfmodel = pycfmodel.parse(template).resolve()
  File "/var/task/pycfmodel/__init__.py", line 19, in parse
    return CFModel(**template)

I've checked and it seems that the template is parsed indeed, but instead of a dict, it is a string. Do you have any clues why this might be happening?

Atm I am triggering the lambda with a test input like this

{
  "project": "test",
  "stack": {
    "name": "stack-name"
  },
  "region": "eu-west-1",
  "account": {
    "id": 1122334455
  }
}

PrivilegeEscalationRule bypass

I can bypass the PrivilegeEscalationRule by simply changing the case of my IAM policy.

eg this passes

iam:CreateAccessKey

but changing to

IAM:CreateAccessKey

will fail, however in the documentation the correct way to specify an iam policy is with all lower case, so the use of intersection should be changed to be case-insensitive (search for IAM: on this page https://docs.aws.amazon.com/comprehend/latest/dg/access-control-managing-permissions.html

intersection = actions.intersection(self.IAM_BLACKLIST)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.