Exemple #1
0
 def test_admin_can_do_anything(self):
     graph = build_graph_with_one_admin()
     principal = graph.nodes[0]
     self.assertTrue(local_check_authorization(principal, 'iam:PutUserPolicy', '*', {}))
     self.assertTrue(local_check_authorization(principal, 'iam:PutUserPolicy', principal.arn, {}))
     self.assertTrue(local_check_authorization(principal, 'iam:CreateRole', '*', {}))
     self.assertTrue(local_check_authorization(principal, 'sts:AssumeRole', '*', {}))
Exemple #2
0
def gen_os_lpe_finding(graph: Graph) -> List[Finding]:
    """Generates findings related to risk of SSM permissions being misconfigured (local priv-esc on the host)"""
    result = []
    affected_roles = []
    for node in graph.nodes:
        if ':role/' in node.arn and node.instance_profile is not None and len(
                node.instance_profile) > 0:
            # https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-setting-up-messageAPIs.html
            if query_interface.local_check_authorization(
                    node, 'ssmmessages:*', '*', {}):
                if query_interface.local_check_authorization(
                        node, 'ssm:SendCommand', '*', {}):
                    affected_roles.append(node)
                elif query_interface.local_check_authorization(
                        node, 'ssm:StartSession', '*', {}):
                    affected_roles.append(node)

    if len(affected_roles) > 0:
        description_preamble = 'In AWS EC2, instances can be assigned instance profiles. An instance profile is tied ' \
                               'to a single IAM Role. The instance profile can be used to access the AWS API with ' \
                               'the permissions of the IAM Role. If the IAM Role has permission to call certain SSM ' \
                               'actions such as `ssm:SendCommand` or `ssm:StartSession`, the instance profile ' \
                               'can be used to invoke commands on other instances or itself.' \
                               '\n' \
                               '\n' \
                               'Because the SSM Agent runs with the highest permissions on their hosts ' \
                               '(root or SYSTEM), this can be a way for attackers to pivot and compromise other ' \
                               'instances, or escalate privileges on the local machine. The following IAM Roles ' \
                               'are attached to at least one instance profile and have permissions with the ' \
                               'aforementioned risk:' \
                               '\n' \
                               '\n'

        description_body = ''
        for node in affected_roles:
            description_body += '* {}\n'.format(node.searchable_name())

        result.append(
            Finding(
                'IAM Roles With Unsafe SSM Permissions'
                if len(affected_roles) > 1 else
                'IAM Role With Unsafe SSM Permissions', 'Medium',
                'If an attacker gains access to an instance with the unsafe permissions, they could escalate privileges '
                'on its current host or compromise other hosts.',
                description_preamble + description_body,
                'Reduce the scope of permissions attached to the noted IAM Role(s).'
            ))

    return result
    def test_permissions_boundary_no_resource_policy(self):
        """In the case of no resource policy, the effective permissions are the "intersection" of the caller's
        identity policies + the boundary policy. Both the user's identity policies + boundary policy must
        permit the API call. A matching deny statement in either set will deny the whole call.
        """
        boundary = Policy(
            'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess',
            'AmazonS3ReadOnlyAccess',
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": [
                            "s3:Get*",
                            "s3:List*"
                        ],
                        "Resource": "*",
                        "Effect": "Allow"
                    }
                ]
            }
        )

        iam_user_1 = _build_user_with_policy(
            {
                'Version': '2012-10-17',
                'Statement': [{
                    'Effect': 'Allow',
                    'Action': '*',
                    'Resource': '*'
                }]
            },
            'admin_policy',
            'asdf1',
            '1'
        )

        iam_user_1.permissions_boundary = boundary

        self.assertTrue(
            local_check_authorization(iam_user_1, 's3:GetObject', 'arn:aws:s3:::bucket/object', {})
        )

        self.assertFalse(
            local_check_authorization(iam_user_1, 's3:PutObject', 'arn:aws:s3:::bucket/object', {})
        )
Exemple #4
0
    def return_edges(self,
                     nodes: List[Node],
                     output: io.StringIO = os.devnull,
                     debug: bool = False) -> List[Edge]:
        """Fulfills expected method return_edges. If session object is None, runs checks in offline mode."""
        result = []
        for node_source in nodes:
            for node_destination in nodes:
                # skip self-access checks
                if node_source == node_destination:
                    continue

                # check if source is an admin, if so it can access destination but this is not tracked via an Edge
                if node_source.is_admin:
                    continue

                # check if destination is a role with an instance profile
                if ':role/' not in node_destination.arn or node_destination.instance_profile is None:
                    continue

                # at this point, we make an assumption that some instance is operating with the given instance profile
                # we assume if the role can call ssmmessages:CreateControlChannel, anyone with ssm perms can access it
                if not query_interface.local_check_authorization(
                        node_destination, 'ssmmessages:CreateControlChannel',
                        '*', {}, False):
                    continue

                # so if source can call ssm:SendCommand or ssm:StartSession, it's an edge
                cmd_auth_res, mfa_res_1 = query_interface.local_check_authorization_handling_mfa(
                    node_source, 'ssm:SendCommand', '*', {}, False)

                if cmd_auth_res:
                    reason = 'can call ssm:SendCommand to access an EC2 instance with access to'
                    if mfa_res_1:
                        reason = '(Requires MFA) ' + reason
                    result.append(Edge(node_source, node_destination, reason))

                sesh_auth_res, mfa_res_2 = query_interface.local_check_authorization_handling_mfa(
                    node_source, 'ssm:StartSession', '*', {}, False)

                if sesh_auth_res:
                    reason = 'can call ssm:StartSession to access an EC2 instance with access to'
                    if mfa_res_2:
                        reason = '(Requires MFA) ' + reason
                    result.append(Edge(node_source, node_destination, reason))

        for edge in result:
            output.write("Found new edge: {}\n".format(edge.describe_edge()))
        return result
Exemple #5
0
def generate_edges_locally(
        nodes: List[Node],
        scps: Optional[List[List[dict]]] = None) -> List[Edge]:
    """Generates and returns Edge objects. It is possible to use this method if you are operating offline (infra-as-code).
    """

    result = []

    for node_destination in nodes:
        # check if destination is a role with an instance profile
        if ':role/' not in node_destination.arn or node_destination.instance_profile is None:
            continue

        # check if the destination can be assumed by EC2
        sim_result = resource_policy_authorization(
            'ec2.amazonaws.com',
            arns.get_account_id(node_destination.arn),
            node_destination.trust_policy,
            'sts:AssumeRole',
            node_destination.arn,
            {},
        )

        if sim_result != ResourcePolicyEvalResult.SERVICE_MATCH:
            continue  # EC2 wasn't auth'd to assume the role

        # at this point, we make an assumption that some instance is operating with the given instance profile
        # we assume if the role can call ssmmessages:CreateControlChannel, anyone with ssm perms can access it
        if not query_interface.local_check_authorization(
                node_destination, 'ssmmessages:CreateControlChannel', '*', {}):
            continue

        for node_source in nodes:
            # skip self-access checks
            if node_source == node_destination:
                continue

            # check if source is an admin, if so it can access destination but this is not tracked via an Edge
            if node_source.is_admin:
                continue

            # so if source can call ssm:SendCommand or ssm:StartSession, it's an edge
            cmd_auth_res, mfa_res_1 = query_interface.local_check_authorization_handling_mfa(
                node_source,
                'ssm:SendCommand',
                '*',
                {},
            )

            if cmd_auth_res:
                reason = 'can call ssm:SendCommand to access an EC2 instance with access to'
                if mfa_res_1:
                    reason = '(Requires MFA) ' + reason
                result.append(
                    Edge(node_source, node_destination, reason, 'SSM'))

            sesh_auth_res, mfa_res_2 = query_interface.local_check_authorization_handling_mfa(
                node_source,
                'ssm:StartSession',
                '*',
                {},
            )

            if sesh_auth_res:
                reason = 'can call ssm:StartSession to access an EC2 instance with access to'
                if mfa_res_2:
                    reason = '(Requires MFA) ' + reason
                result.append(
                    Edge(node_source, node_destination, reason, 'SSM'))

    return result
Exemple #6
0
    def test_arn_condition(self):
        """ Validate the following conditions are correctly handled:
            ArnEquals, ArnLike, ArnNotEquals, ArnNotLike.

            Note, ArnEquals and ArnLike have the same behavior, as well as ArnNotEquals and ArnNotLike

            Validated against the Simulator API

            TODO: Check on ForAnyValue and ForAllValues
        """

        # ArnEquals (and ArnLike) testing: no wildcards
        test_arn_equals = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ArnEquals': {
                        'aws:SourceArn':
                        'arn:aws:iam::000000000000:user/test1',
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_arn_equals, 'iam:CreateUser', '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test1'}))
        self.assertFalse(
            local_check_authorization(
                test_arn_equals, 'iam:CreateUser', '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test2'}))

        # ArnEquals (and ArnLike) testing: wildcards
        test_arn_equals_wild = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ArnEquals': {
                        'aws:SourceArn': 'arn:aws:iam::*:user/test1',
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_arn_equals_wild,
                'iam:CreateUser',
                '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test1'},
            ))
        self.assertFalse(
            local_check_authorization(
                test_arn_equals_wild,
                'iam:CreateUser',
                '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test2'},
            ))

        # ArnNotEquals (and ArnNotLike) testing: wildcards
        test_arn_equals_wild = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ArnNotLike': {
                        'aws:SourceArn': 'arn:aws:iam::*:user/test1',
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(
                test_arn_equals_wild,
                'iam:CreateUser',
                '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test1'},
            ))
        self.assertTrue(
            local_check_authorization(
                test_arn_equals_wild,
                'iam:CreateUser',
                '*',
                {'aws:SourceArn': 'arn:aws:iam::000000000000:user/test2'},
            ))
        self.assertFalse(
            local_check_authorization(
                test_arn_equals_wild,
                'iam:CreateUser',
                '*',
                {'aws:SourceArn': 'test2'},
            ))
Exemple #7
0
    def test_local_mfa_handling(self):
        mfa_policy = Policy(
            arn='arn:aws:iam::000000000000:policy/mfa_policy',
            name='mfa_policy',
            policy_doc={
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Sid":
                    "AllowManageOwnUserMFA",
                    "Effect":
                    "Allow",
                    "Action": [
                        "iam:DeactivateMFADevice", "iam:EnableMFADevice",
                        "iam:GetUser", "iam:ListMFADevices",
                        "iam:ResyncMFADevice"
                    ],
                    "Resource":
                    "arn:aws:iam::*:user/${aws:username}"
                }, {
                    "Sid":
                    "DenyAllExceptListedIfNoMFA",
                    "Effect":
                    "Deny",
                    "NotAction": [
                        "iam:CreateVirtualMFADevice", "iam:EnableMFADevice",
                        "iam:GetUser", "iam:ListMFADevices",
                        "iam:ListVirtualMFADevices", "iam:ResyncMFADevice",
                        "sts:GetSessionToken"
                    ],
                    "Resource":
                    "*",
                    "Condition": {
                        "BoolIfExists": {
                            "aws:MultiFactorAuthPresent": "false"
                        }
                    }
                }]
            })
        s3_policy = Policy(
            'arn:aws:iam::000000000000:policy/s3access', 's3access', {
                "Version":
                "2012-10-17",
                "Statement": [{
                    "Sid": "AllowViewAccountInfo",
                    "Effect": "Allow",
                    "Action": "s3:ListAllMyBuckets",
                    "Resource": "*"
                }]
            })
        test_node = Node('arn:aws:iam::000000000000:user/uses_mfa',
                         'AIDA00000000000000000', [mfa_policy, s3_policy], [],
                         None, None, 1, False, False, None, True, None)

        print(mfa_policy.to_dictionary())
        print(s3_policy.to_dictionary())
        print(test_node.to_dictionary())

        # Test that lack of MFA conditions is not allowed (note the function call diff)
        # This matches policy sim feedback
        auth_result = local_check_authorization(test_node,
                                                's3:ListAllMyBuckets', '*', {})
        self.assertFalse(auth_result)

        # Test that MFA set to false is disallowed
        auth_result, mfa_result = local_check_authorization_handling_mfa(
            test_node, 's3:ListAllMyBuckets', '*',
            {'aws:MultiFactorAuthPresent': 'false'})
        self.assertFalse(auth_result)
        self.assertFalse(mfa_result)

        # Test that testing both with and without MFA yields correct results
        auth_result, mfa_result = local_check_authorization_handling_mfa(
            test_node, 's3:ListAllMyBuckets', '*', {})
        self.assertTrue(auth_result)
        self.assertTrue(mfa_result)

        # Test that iam:EnableMFADevice is allowed despite lack of MFA
        auth_result, mfa_result = local_check_authorization_handling_mfa(
            test_node, 'iam:EnableMFADevice',
            'arn:aws:iam::000000000000:user/uses_mfa', {})

        self.assertFalse(mfa_result)
        self.assertTrue(auth_result)
Exemple #8
0
    def test_documented_ddb_authorization_behavior(self):
        test_node = _build_user_with_policy({
            "Version":
            "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Action": "dynamodb:GetItem",
                "Resource": "arn:aws:dynamodb:*:*:table/Thread",
                "Condition": {
                    "ForAllValues:StringEquals": {
                        "dynamodb:Attributes": ["ID", "Message", "Tags"]
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:attributes': ['ID', 'Message', 'Tags']}))
        self.assertTrue(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:attributes': ['ID', 'Message']}))
        self.assertTrue(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread', {}))
        self.assertFalse(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:Attributes': ['ID', 'Message', 'Tags', 'Password']
                 }))

        test_node = _build_user_with_policy({
            "Version":
            "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Action": "dynamodb:GetItem",
                "Resource": "arn:aws:dynamodb:*:*:table/Thread",
                "Condition": {
                    "ForAnyValue:StringEquals": {
                        "dynamodb:Attributes": ["ID", "Message", "Tags"]
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:Attributes': ['ID', 'Message', 'Tags']}))
        self.assertTrue(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:Attributes': ['Tags', 'Password']}))
        self.assertFalse(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread',
                {'dynamodb:Attributes': ['Password']}))
        self.assertFalse(
            local_check_authorization(
                test_node, 'dynamodb:GetItem',
                'arn:aws:dynamodb:us-west-2:000000000000:table/Thread', {}))
Exemple #9
0
    def test_bool_condition_handling(self):
        """ Validate the following conditions are handled:
            * Bool

            TODO: Check on ForAnyValue and ForAllValues
        """
        # Bool: true
        test_node_true = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'Bool': {
                        'aws:SecureTransport': 'true'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_true, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'true'}))
        self.assertTrue(
            local_check_authorization(test_node_true, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'True'}))
        self.assertFalse(
            local_check_authorization(test_node_true, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'tru'}))
        self.assertFalse(
            local_check_authorization(test_node_true, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': ''}))
        self.assertFalse(
            local_check_authorization(test_node_true, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'false'}))

        # Bool: false
        test_node_false = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'Bool': {
                        'aws:SecureTransport': 'false'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_false, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'false'}))
        self.assertFalse(
            local_check_authorization(test_node_false, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 'true'}))
        self.assertTrue(
            local_check_authorization(
                test_node_false, 'iam:CreateUser', '*',
                {'aws:SecureTransport': 'asdf'}))  # policy sim behavior
        self.assertTrue(
            local_check_authorization(test_node_false, 'iam:CreateUser', '*',
                                      {'aws:SecureTransport': 't'}))
Exemple #10
0
    def test_ipaddress_condition_handling(self):
        """ Validate the following conditions are handled:
            * IpAddress
            * NotIpAddress

            TODO: Check on ForAnyValue and ForAllValues
        """
        # IpAddress: single IP
        test_node_ipaddress = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'IpAddress': {
                        'aws:SourceIp': '10.0.0.1'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '10.0.0.1'}))
        self.assertFalse(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '10.0.0.2'}))

        # IpAddress: IP range
        test_node_ipaddress = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'IpAddress': {
                        'aws:SourceIp': '10.0.0.0/8'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '10.0.0.1'}))
        self.assertFalse(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '127.0.0.1'}))

        # IpAddress: IP ranges
        test_node_ipaddress = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'IpAddress': {
                        'aws:SourceIp': ['10.0.0.0/8', '127.0.0.0/8']
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '10.0.0.1'}))
        self.assertTrue(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '127.0.0.1'}))
        self.assertFalse(
            local_check_authorization(test_node_ipaddress, 'iam:CreateUser',
                                      '*', {'aws:SourceIp': '192.168.0.1'}))
Exemple #11
0
    def test_datetime_condition_handling(self):
        """ Validate the following conditions are correctly handled:
            DateEquals
            DateNotEquals
            DateLessThan
            DateLessThanEquals
            DateGreaterThan
            DateGreaterThanEquals

            TODO: Check on ForAnyValue and ForAllValues
        """
        # DateEquals
        test_node_date_equals = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateEquals': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_node_date_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:00Z'}))
        self.assertTrue(
            local_check_authorization(test_node_date_equals, 'iam:CreateUser',
                                      '*',
                                      {'aws:CurrentTime': '1533859200.0'}))
        self.assertTrue(
            local_check_authorization(test_node_date_equals, 'iam:CreateUser',
                                      '*', {'aws:CurrentTime': '1533859200'}))
        self.assertFalse(
            local_check_authorization(test_node_date_equals, 'iam:CreateUser',
                                      '*', {'aws:CurrentTime': '1533859201'}))
        self.assertFalse(
            local_check_authorization(
                test_node_date_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))

        # DateNotEquals
        test_node_date_not_equals = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateNotEquals': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(
                test_node_date_not_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:00Z'}))
        self.assertTrue(
            local_check_authorization(
                test_node_date_not_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))

        # DateGreaterThan
        test_node_date_greater_than = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateGreaterThan': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(
                test_node_date_greater_than, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:00Z'}))
        self.assertTrue(
            local_check_authorization(
                test_node_date_greater_than, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))

        # DateGreaterThanEquals
        test_node_date_greater_than_equals = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateGreaterThanEquals': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(
                test_node_date_greater_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-09T23:59:59Z'}))
        self.assertTrue(
            local_check_authorization(
                test_node_date_greater_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:00Z'}))
        self.assertTrue(
            local_check_authorization(
                test_node_date_greater_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))

        # DateLessThan
        test_node_date_less_than = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateLessThan': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_node_date_less_than, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-09T23:59:59Z'}))
        self.assertFalse(
            local_check_authorization(
                test_node_date_less_than, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))

        # DateLessThanEquals
        test_node_date_less_than_equals = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'DateLessThanEquals': {
                        'aws:CurrentTime': '2018-08-10T00:00:00Z'
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(
                test_node_date_less_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-09T23:59:59Z'}))
        self.assertTrue(
            local_check_authorization(
                test_node_date_less_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:00Z'}))
        self.assertFalse(
            local_check_authorization(
                test_node_date_less_than_equals, 'iam:CreateUser', '*',
                {'aws:CurrentTime': '2018-08-10T00:00:01Z'}))
Exemple #12
0
    def test_null_condition_handling(self):
        """ Validate the following conditions are correctly handled:
            Null, ForAnyValue:Null, ForAllValues:Null

            Validated against the Simulator API
        """

        # Basic use validation
        test_node_null = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'Null': {
                        'aws:username':
                        '******',  # aws:username MUST NOT be present
                        'aws:userid': 'false'  # aws:userid MUST be present
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_null, 'iam:CreateUser', '*', {
                'aws:userid': 'asdf',
                'aws:username': ''
            }))
        self.assertFalse(
            local_check_authorization(test_node_null, 'iam:CreateUser', '*', {
                'aws:userid': '',
                'aws:username': ''
            }))

        # Array use validation
        test_node_null_array = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'Null': {
                        'aws:username':
                        ['true', 'false'],  # doesn't matter if it's in or not
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_null_array, 'iam:CreateUser',
                                      '*', {'aws:username': ''}))
        self.assertTrue(
            local_check_authorization(test_node_null_array, 'iam:CreateUser',
                                      '*', {'aws:username': '******'}))

        # ForAllValues: validation
        test_node_null_forallvalues_1 = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ForAllValues:Null': {  # For all valid context values...
                        'aws:username':
                        '******',  # aws:username MUST be present
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_null_forallvalues_1,
                                      'iam:CreateUser', '*',
                                      {'aws:username': '******'}))
        self.assertTrue(
            local_check_authorization(test_node_null_forallvalues_1,
                                      'iam:CreateUser', '*',
                                      {'aws:username': ''}))
        test_node_null_forallvalues_2 = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ForAllValues:Null': {  # For all valid context values...
                        'aws:username':
                        '******',  # aws:username MUST NOT be present
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(test_node_null_forallvalues_2,
                                      'iam:CreateUser', '*',
                                      {'aws:username': '******'}))
        self.assertTrue(
            local_check_authorization(test_node_null_forallvalues_2,
                                      'iam:CreateUser', '*',
                                      {'aws:username': ''}))

        # ForAnyValue: validation
        test_node_null_foranyvalue_1 = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ForAnyValue:Null': {  # Among the valid context values...
                        'aws:username':
                        '******',  # aws:username MUST NOT be present (cannot fulfill this)
                    }
                }
            }]
        })
        self.assertFalse(
            local_check_authorization(test_node_null_foranyvalue_1,
                                      'iam:CreateUser', '*',
                                      {'aws:username': '******'}))
        self.assertFalse(
            local_check_authorization(test_node_null_foranyvalue_1,
                                      'iam:CreateUser', '*',
                                      {'aws:username': ''}))

        test_node_null_foranyvalue_2 = _build_user_with_policy({
            'Version':
            '2012-10-17',
            'Statement': [{
                'Effect': 'Allow',
                'Action': '*',
                'Resource': '*',
                'Condition': {
                    'ForAnyValue:Null': {  # Among the valid context values...
                        'aws:username':
                        '******',  # aws:username MUST be present
                    }
                }
            }]
        })
        self.assertTrue(
            local_check_authorization(test_node_null_foranyvalue_2,
                                      'iam:CreateUser', '*',
                                      {'aws:username': '******'}))
        self.assertFalse(
            local_check_authorization(test_node_null_foranyvalue_2,
                                      'iam:CreateUser', '*',
                                      {'aws:username': ''}))