def invoke(self,
            cfmodel: CFModel,
            extras: Optional[Dict] = None) -> Result:
     result = Result()
     for logical_id, resource in cfmodel.Resources.items():
         if isinstance(resource,
                       IAMManagedPolicy) and resource.Properties.Users:
             self.add_failure_to_result(
                 result,
                 self.REASON.format(logical_id),
                 resource_ids={logical_id},
                 resource_types={resource.Type},
                 context={
                     "config": self._config,
                     "extras": extras,
                     "logical_id": logical_id,
                     "resource": resource
                 },
             )
     return result
Exemplo n.º 2
0
def test_with_templates(cf_path):
    with open(cf_path) as cf_script:
        cf_template = convert_json_or_yaml_to_dict(cf_script.read())

    config = Config(project_name=cf_path, service_name=cf_path, stack_name=cf_path, rules=DEFAULT_RULES.keys())

    # Scan result
    result = Result()

    cfmodel = pycfmodel.parse(cf_template).resolve()

    rules = [DEFAULT_RULES.get(rule)(config, result) for rule in config.rules]
    processor = RuleProcessor(*rules)
    processor.process_cf_template(cfmodel, config, result)

    # Use this to print the stack if there'IAMManagedPolicyWildcardActionRule an error
    if len(result.exceptions):
        print(cf_path)
        traceback.print_tb(result.exceptions[0].__traceback__)

    assert len(result.exceptions) == 0
Exemplo n.º 3
0
    def test_security_group_rules_as_refs(self):

        role_props = {
            "AWSTemplateFormatVersion": "2010-09-09",
            "Resources": {
                "RootRole": {
                    "Type": "AWS::EC2::SecurityGroup",
                    "Properties": {
                        "SecurityGroupIngress": [{"CidrIp": {"Ref": "MyParam"}, "FromPort": 22, "ToPort": 22}]
                    },
                }
            },
        }

        result = Result()
        rule = SecurityGroupOpenToWorldRule(None, result)
        resources = parse(role_props).resources
        rule.invoke(resources, [])

        assert result.valid
        assert len(result.failed_rules) == 0
Exemplo n.º 4
0
 def invoke(self,
            cfmodel: CFModel,
            extras: Optional[Dict] = None) -> Result:
     result = Result()
     for logical_id, resource in cfmodel.Resources.items():
         if isinstance(resource,
                       (IAMManagedPolicy, IAMPolicy, S3BucketPolicy,
                        SNSTopicPolicy, SQSQueuePolicy)):
             self.check_for_wildcards(result, logical_id,
                                      resource.Properties.PolicyDocument,
                                      extras)
         elif isinstance(resource, (IAMRole, IAMUser)):
             if isinstance(resource, IAMRole):
                 self.check_for_wildcards(
                     result, logical_id,
                     resource.Properties.AssumeRolePolicyDocument, extras)
             if resource.Properties and resource.Properties.Policies:
                 for policy in resource.Properties.Policies:
                     self.check_for_wildcards(result, logical_id,
                                              policy.PolicyDocument, extras)
     return result
Exemplo n.º 5
0
 def resource_invoke(self,
                     resource: S3Bucket,
                     logical_id: str,
                     extras: Optional[Dict] = None) -> Result:
     result = Result()
     version_configuration_status = getattr(
         resource.Properties.VersioningConfiguration, "Status", None)
     if version_configuration_status != self.ENABLED_STATUS:
         self.add_failure_to_result(
             result,
             self.REASON.format(logical_id),
             resource_ids={logical_id},
             resource_types={resource.Type},
             context={
                 "config": self._config,
                 "extras": extras,
                 "logical_id": logical_id,
                 "resource": resource
             },
         )
     return result
Exemplo n.º 6
0
    def invoke(self,
               cfmodel: CFModel,
               extras: Optional[Dict] = None) -> Result:
        result = Result()
        for logical_id, resource in cfmodel.resources_filtered_by_type(
                "AWS::EC2::Volume").items():
            encrypted_status = getattr(resource.Properties, "Encrypted", None)

            if encrypted_status is None or encrypted_status is False:
                self.add_failure_to_result(
                    result,
                    self.REASON.format(logical_id),
                    resource_ids={logical_id},
                    resource_types={resource.Type},
                    context={
                        "config": self._config,
                        "extras": extras,
                        "logical_id": logical_id,
                        "resource": resource
                    },
                )
        return result
Exemplo n.º 7
0
    def invoke(self,
               cfmodel: CFModel,
               extras: Optional[Dict] = None) -> Result:
        result = Result()
        for logical_id, resource in cfmodel.Resources.items():
            if isinstance(resource, IAMRole):
                # check AssumeRolePolicyDocument.
                if resource.Properties.AssumeRolePolicyDocument.allowed_actions_with(
                        REGEX_WILDCARD_POLICY_ACTION):
                    self.add_failure_to_result(
                        result,
                        self.REASON.format(logical_id, "AssumeRolePolicy"),
                        resource_ids={logical_id},
                    )

                # check other policies of the IAM role.
                if resource.Properties.Policies:
                    for policy in resource.Properties.Policies:
                        if policy.PolicyDocument.allowed_actions_with(
                                REGEX_WILDCARD_POLICY_ACTION):
                            self.add_failure_to_result(
                                result,
                                self.REASON.format(
                                    logical_id, f"{policy.PolicyName} policy"),
                                resource_ids={logical_id},
                            )

            # check AWS::IAM::ManagedPolicy.
            elif isinstance(
                    resource, IAMManagedPolicy
            ) and resource.Properties.PolicyDocument.allowed_actions_with(
                    REGEX_WILDCARD_POLICY_ACTION):
                self.add_failure_to_result(
                    result,
                    self.REASON.format(logical_id, "AWS::IAM::ManagedPolicy"),
                    resource_ids={logical_id},
                )
        return result
Exemplo n.º 8
0
    def resource_invoke(self, resource: S3BucketPolicy,
                        logical_id: str) -> Result:
        result = Result()

        for statement in resource.Properties.PolicyDocument._statement_as_list(
        ):
            for principal in statement.get_principal_list():
                account_id = get_account_id_from_principal(principal)
                if not account_id:
                    continue
                if account_id not in self.valid_principals:
                    if statement.Condition and statement.Condition.dict():
                        logger.warning(
                            f"Not adding {type(self).__name__} failure in {logical_id} "
                            f"because there are conditions: {statement.Condition}"
                        )
                    else:
                        self.add_failure_to_result(
                            result,
                            self.REASON.format(logical_id, account_id),
                            resource_ids={logical_id},
                        )
        return result
Exemplo n.º 9
0
    def test_invalid_security_group_multiple_statements(self):
        role_props = {
            "AWSTemplateFormatVersion": "2010-09-09",
            "Resources": {
                "RootRole": {
                    "Type": "AWS::EC2::SecurityGroup",
                    "Properties": {
                        "SecurityGroupIngress": [
                            {"CidrIp": "10.0.0.0/8", "FromPort": 22, "ToPort": 22},
                            {"CidrIp": "0.0.0.0/0", "FromPort": 9090, "ToPort": 9090},
                        ]
                    },
                }
            },
        }

        result = Result()
        rule = SecurityGroupOpenToWorldRule(None, result)
        resources = parse(role_props).resources
        rule.invoke(resources, [])

        assert result.failed_rules[0]["reason"] == 'Port 9090 open to the world in security group "RootRole"'
        assert result.failed_rules[0]["rule"] == "SecurityGroupOpenToWorldRule"
Exemplo n.º 10
0
    def test_with_templates(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        test_templates = glob.glob('{}/test_templates/*.*'.format(dir_path))
        for template in test_templates:
            cf_script = open(template)
            cf_template = S3Adapter().convert_json_or_yaml_to_dict(
                cf_script.read())

            config = Config(
                project_name=template,
                service_name=template,
                stack_name=template,
                rules=ALL_RULES.keys(),
            )

            # Scan result
            result = Result()

            rules = [
                ALL_RULES.get(rule)(config, result) for rule in config.RULES
            ]
            processor = RuleProcessor(*rules)

            processor.process_cf_template(cf_template, config, result)
            # Use this to print the stack if there's an error
            if len(result.exceptions):
                print(template)
                traceback.print_tb(result.exceptions[0].__traceback__)

            no_resource_templates = [
                'vulgar_bad_syntax.yml',
                'rubbish.json',
            ]
            if template.split('/')[-1] in no_resource_templates:
                assert len(result.exceptions) == 1
            else:
                assert len(result.exceptions) == 0
def test_failures_are_raised(bad_template):
    result = Result()
    rule = GenericWildcardPrincipalRule(None, result)
    rule.invoke(bad_template)

    assert result.valid
    assert len(result.failed_rules) == 0
    assert len(result.failed_monitored_rules) == 3
    assert result.failed_monitored_rules[
        0].rule == "GenericWildcardPrincipalRule"
    assert (
        result.failed_monitored_rules[0].reason ==
        "PolicyA should not allow wildcard in principals or account-wide principals "
        "(principal: 'somewhatrestricted:*')")
    assert result.failed_monitored_rules[
        1].rule == "GenericWildcardPrincipalRule"
    assert result.failed_monitored_rules[
        1].reason == "PolicyA contains an unknown principal: 123445"
    assert result.failed_monitored_rules[
        2].rule == "GenericWildcardPrincipalRule"
    assert (
        result.failed_monitored_rules[2].reason ==
        "PolicyA should not allow wildcard in principals or account-wide principals "
        "(principal: 'arn:aws:iam::123445:*')")