Пример #1
0
    def test_findings_add_list(self):
        """output.findings.findings.add: Make sure the add function works with adding it as a list"""
        test_policy = {
            "Version":
            "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Action": ["s3:GetObject"],
                "Resource": "*"
            }]
        }
        policy_document = PolicyDocument(test_policy)
        finding_1 = Finding(
            policy_name="MyPolicy",
            arn="arn:aws:iam::123456789012:group/SNSNotifications",
            actions=["s3:GetObject"],
            policy_document=policy_document)
        finding_2 = Finding(policy_name="MyPolicy",
                            arn="arn:aws:iam::aws:policy/BadAWSManagedPolicy",
                            actions=["s3:GetObject"],
                            policy_document=policy_document)

        findings = Findings()
        findings.add([finding_1, finding_2])
        result = findings.json
        self.assertTrue(len(result) == 2)
Пример #2
0
 def test_finding_actions_excluded(self):
     test_policy = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Effect":
             "Allow",
             "Action":
             ["s3:GetObject", "logs:CreateLogStream", "logs:PutLogEvents"],
             "Resource":
             "*"
         }]
     }
     policy_document = PolicyDocument(test_policy)
     # (1) EXCLUDE actions
     exclusions_cfg = {
         "users": ["obama"],
         "groups": ["admin"],
         "roles": ["MyRole"],
         "policies": ["someOtherName"],
         "exclude-actions": ["logs:CreateLogStream", "logs:PutLogEvents"]
     }
     exclusions = Exclusions(exclusions_cfg)
     finding = Finding(
         policy_name="MyPolicy",
         arn="arn:aws:iam::123456789012:group/SNSNotifications",
         actions=["s3:GetObject"],
         policy_document=policy_document,
         exclusions=exclusions)
     # print(finding.actions)
     self.assertListEqual(finding.actions, ["s3:GetObject"])
 def test_findings_excluded(self):
     test_policy = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "s3:GetObject",
                     "logs:CreateLogStream",
                     "logs:PutLogEvents"
                 ],
                 "Resource": "*"
             }
         ]
     }
     policy_document = PolicyDocument(test_policy)
     always_exclude_actions = [
         "logs:CreateLogStream",
         "logs:PutLogEvents"
     ]
     finding = Finding(
         policy_name="MyPolicy",
         arn="arn:aws:iam::123456789012:group/SNSNotifications",
         actions=["s3:GetObject"],
         policy_document=policy_document,
         always_exclude_actions=always_exclude_actions
     )
     print(finding.actions)
     self.assertListEqual(finding.actions, ["s3:GetObject"])
Пример #4
0
 def test_finding_attributes(self):
     """scan.findings.new_finding"""
     test_policy = {
         "Version":
         "2012-10-17",
         "Statement": [{
             "Effect": "Allow",
             "Action": ["s3:GetObject"],
             "Resource": "*"
         }]
     }
     policy_document = PolicyDocument(test_policy)
     finding = Finding(
         policy_name="MyPolicy",
         arn="arn:aws:iam::123456789012:group/SNSNotifications",
         actions=["s3:GetObject"],
         policy_document=policy_document)
     self.assertEqual(finding.account_id, "123456789012")
     self.assertEqual(finding.managed_by, "Customer")
     self.assertEqual(len(finding.services_affected), 1)
     self.assertEqual(len(finding.actions), 1)
     self.assertDictEqual(finding.policy_document.json,
                          policy_document.json)
     expected_finding_json = {
         "AccountID": "123456789012",
         "ManagedBy": "Customer",
         "Name": "SNSNotifications",
         "PolicyName": "MyPolicy",
         "Type": "Group",
         "Arn": "arn:aws:iam::123456789012:group/SNSNotifications",
         "ActionsCount": 1,
         "ServicesCount": 1,
         "Services": ["s3"],
         "Actions": ["s3:GetObject"],
         "PolicyDocument": {
             "Version":
             "2012-10-17",
             "Statement": [{
                 "Effect": "Allow",
                 "Action": ["s3:GetObject"],
                 "Resource": "*"
             }]
         },
         "AssumableByComputeService": [],
         "AssumeRolePolicyDocument": None,
         "PrivilegeEscalation": [],
         "DataExfiltrationActions": ["s3:GetObject"],
         "PermissionsManagementActions": [],
     }
     # print(json.dumps(finding.json, indent=4))
     self.maxDiff = None
     self.assertDictEqual(finding.json, expected_finding_json)
Пример #5
0
def scan_policy(policy_json, policy_name, exclusions_cfg=DEFAULT_EXCLUSIONS_CONFIG):
    """
    Scan a policy document for missing resource constraints.

    :param policy_json: The AWS IAM policy document.
    :param exclusions_cfg: Defaults to the embedded exclusions file, which has no effect here.
    :param policy_name: The name of the IAM policy. Defaults to the filename when used from command line.
    :return:
    """
    policy_document = PolicyDocument(policy_json)
    actions_missing_resource_constraints = []

    # EXCLUDED ACTIONS - actions to exclude if they are false positives
    excluded_actions = exclusions_cfg.get("exclude-actions", None)
    if excluded_actions == [""]:
        excluded_actions = None

    # convert to lowercase for comparison purposes
    # some weird if/else logic to reduce loops and improve performance slightly
    if excluded_actions:
        excluded_actions = [x.lower() for x in excluded_actions]

    always_include_actions = exclusions_cfg.get("include-actions")
    findings = Findings()

    for statement in policy_document.statements:
        if statement.effect == "Allow":
            actions_missing_resource_constraints.extend(
                statement.missing_resource_constraints_for_modify_actions(
                    always_include_actions
                )
            )
    if actions_missing_resource_constraints:
        results_placeholder = []
        for action in actions_missing_resource_constraints:
            if excluded_actions:
                if not is_name_excluded(action.lower(), excluded_actions):
                    results_placeholder.append(action)  # pragma: no cover
            else:
                results_placeholder.append(action)
        actions_missing_resource_constraints = list(
            dict.fromkeys(results_placeholder)
        )  # remove duplicates
        actions_missing_resource_constraints.sort()
        finding = Finding(
            policy_name=policy_name,
            arn=policy_name,
            actions=actions_missing_resource_constraints,
            policy_document=policy_document,
        )
        findings.add(finding)
    return findings.json
Пример #6
0
 def test_finding_actions_included(self):
     test_policy = {
         "Version": "2012-10-17",
         "Statement": [
             {
                 "Effect": "Allow",
                 "Action": [
                     "s3:GetObject",
                     "ec2:DescribeInstances",  # This is a bad thing to include, but just for the hell of it
                 ],
                 "Resource": "*"
             }
         ]
     }
     policy_document = PolicyDocument(test_policy)
     # (2) INCLUDE actions
     exclusions_cfg = {
         "users": ["obama"],
         "groups": ["admin"],
         "roles": ["MyRole"],
         "policies": ["someOtherName"],
         "include-actions": [
             "ec2:DescribeInstances"
         ],
         "exclude-actions": [
             "s3:GetObject",
         ],
     }
     exclusions = Exclusions(exclusions_cfg)
     finding = Finding(
         policy_name="MyPolicy",
         arn="arn:aws:iam::123456789012:group/SNSNotifications",
         actions=["s3:GetObject", "ec2:DescribeInstances"],
         policy_document=policy_document,
         exclusions=exclusions
     )
     # print(finding.actions)
     expected_results = [
         "ec2:DescribeInstances",
     ]
     self.assertListEqual(finding.actions, expected_results)
     group_finding = GroupFinding(
         policy_name="MyPolicy",
         arn="arn:aws:iam::123456789012:group/SNSNotifications",
         actions=["s3:GetObject", "ec2:DescribeInstances"],
         policy_document=policy_document,
         exclusions=exclusions,
         members=None
     )
     self.assertListEqual(group_finding.actions, expected_results)
Пример #7
0
    def test_findings_for_roles_assumable_by_compute_services_ecs_tasks_new(self):
        trust_policy_from_compute_service_ecs_tasks = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "sts:AssumeRole"
                    ],
                    "Principal": {
                        "Service": "ecs-tasks.amazonaws.com",
                        "AWS": "arn:aws:iam::012345678910:root",
                    }
                }
            ]
        }
        assume_role_policy_document = AssumeRolePolicyDocument(trust_policy_from_compute_service_ecs_tasks)

        test_policy = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "s3:GetObject"
                    ],
                    "Resource": "*"
                }
            ]
        }
        policy_document = PolicyDocument(test_policy)
        finding = Finding(
            policy_name="MyPolicy",
            arn="arn:aws:iam::123456789012:role/TestComputeService",
            actions=["s3:GetObject"],
            policy_document=policy_document,
            assume_role_policy_document=assume_role_policy_document
        )
        # print(finding.role_assumable_by_compute_services)
        self.assertListEqual(finding.role_assumable_by_compute_services, ["ecs-tasks"])

        role_finding = RoleFinding(
            policy_name="MyPolicy",
            arn="arn:aws:iam::123456789012:role/TestComputeService",
            actions=["s3:GetObject"],
            policy_document=policy_document,
            assume_role_policy_document=assume_role_policy_document
        )
        self.assertListEqual(role_finding.role_assumable_by_compute_services, ["ecs-tasks"])
Пример #8
0
    def scan_principal_type_details(
        self,
        principal_type_detail_list,
        exclusions_cfg=DEFAULT_EXCLUSIONS_CONFIG,
        modify_only=True,
    ):
        """Scan the UserDetailList, GroupDetailList, or RoleDetailList blocks of the account authorization details output."""
        excluded_actions = exclusions_cfg.get("exclude-actions", None)

        for principal in principal_type_detail_list.principals:
            always_include_actions = exclusions_cfg.get("include-actions")
            print(f"Scanning {principal.principal_type}: {principal.name}")
            for policy in principal.policy_list:
                print(f"\tScanning Policy: {policy['PolicyName']}")

                if is_name_excluded(policy["PolicyName"],
                                    exclusions_cfg.get("policies")):
                    print(f"\tExcluded policy name: {policy['PolicyName']}")
                elif principal.is_principal_excluded(exclusions_cfg):
                    print(f"\tExcluded principal name: {principal.name}")
                else:
                    policy_document = policy["PolicyDocument"]
                    actions_missing_resource_constraints = []
                    for statement in policy_document.statements:
                        if modify_only:
                            if statement.effect == "Allow":
                                actions_missing_resource_constraints.extend(
                                    statement.
                                    missing_resource_constraints_for_modify_actions(
                                        always_include_actions))
                        else:
                            if statement.effect == "Allow":
                                actions_missing_resource_constraints.extend(
                                    statement.missing_resource_constraints)
                    if actions_missing_resource_constraints:
                        finding = Finding(
                            policy_name=policy["PolicyName"],
                            arn=principal.arn,
                            actions=actions_missing_resource_constraints,
                            policy_document=policy["PolicyDocument"],
                            assume_role_policy_document=principal.
                            assume_role_policy_document,
                            always_exclude_actions=excluded_actions)
                        self.findings.add(finding)
    def test_findings_for_roles_assumable_by_compute_services_empty(self):
        """output.findings.role_assumable_by_compute_services"""
        trust_policy_from_non_compute_service = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "sts:AssumeRole"
                    ],
                    "Principal": {
                        "Service": ["yolo.amazonaws.com"]
                    }
                }
            ]
        }
        assume_role_policy_document = AssumeRolePolicyDocument(trust_policy_from_non_compute_service)

        test_policy = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Action": [
                        "s3:GetObject"
                    ],
                    "Resource": "*"
                }
            ]
        }
        policy_document = PolicyDocument(test_policy)
        finding = Finding(
            policy_name="MyPolicy",
            arn="arn:aws:iam::123456789012:role/TestComputeService",
            actions=["s3:GetObject"],
            policy_document=policy_document,
            assume_role_policy_document=assume_role_policy_document
        )
        self.assertListEqual(finding.role_assumable_by_compute_services, [])
        # print(json.dumps(finding.assume_role_policy_document_json, indent=4))
        self.assertDictEqual(finding.assume_role_policy_document_json, trust_policy_from_non_compute_service)
Пример #10
0
    def scan_policy_details(self,
                            exclusions_cfg=DEFAULT_EXCLUSIONS_CONFIG,
                            modify_only=True):
        """Scan the PolicyDetails block of the account authorization details output."""
        excluded_actions = exclusions_cfg.get("exclude-actions", None)

        for policy in self.policies.policy_details:
            print(f"Scanning policy: {policy.policy_name}")
            always_include_actions = exclusions_cfg.get("include-actions")
            actions_missing_resource_constraints = []
            if is_name_excluded(policy.policy_name,
                                exclusions_cfg.get("policies")):
                print(f"\tExcluded policy name: {policy.policy_name}")
            elif is_name_excluded(policy.full_policy_path,
                                  exclusions_cfg.get("policies")):
                print(f"\tExcluded policy path: {policy.full_policy_path}")
            else:
                for statement in policy.policy_document.statements:
                    if modify_only:
                        if statement.effect == "Allow":
                            actions_missing_resource_constraints.extend(
                                statement.
                                missing_resource_constraints_for_modify_actions(
                                    always_include_actions))
                    else:
                        if statement.effect == "Allow":
                            actions_missing_resource_constraints.extend(
                                statement.missing_resource_constraints)
                if actions_missing_resource_constraints:
                    actions_missing_resource_constraints = list(
                        dict.fromkeys(actions_missing_resource_constraints)
                    )  # remove duplicates
                    actions_missing_resource_constraints.sort()
                    finding = Finding(
                        policy_name=policy.policy_name,
                        arn=policy.arn,
                        actions=actions_missing_resource_constraints,
                        policy_document=policy.policy_document,
                        always_exclude_actions=excluded_actions)
                    self.findings.add(finding)