Skip to content

Exception When Policy is Only Used as Permission Boundary #121

Open

Description

@brandonstevens

Describe the bug
PMapper throws an exception and exits when attempting to graph an AWS Account that contains an IAM identity that includes a Permission Boundary that has not other usage. i.e. a managed policy is not attached to any identities and only used as a permission boundary.

$  pmapper graph create
2022-11-01 17:29:59+0000 | Obtaining IAM Users/Roles/Groups/Policies in the account.
2022-11-01 17:30:10+0000 | Sorting users, roles, groups, policies, and their relationships.
Traceback (most recent call last):
  File "/usr/local/bin/pmapper", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/site-packages/principalmapper/__main__.py", line 145, in main
    return graph_cli.process_arguments(parsed_args)
  File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/graph_cli.py", line 179, in process_arguments
    graph = graph_actions.create_new_graph(session, service_list, parsed_args.include_regions,
  File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/graph_actions.py", line 39, in create_new_graph
    return gathering.create_graph(session, service_list, region_allow_list, region_deny_list, scps, client_args_map)
  File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/gathering.py", line 75, in create_graph
    results = get_nodes_groups_and_policies(iamclient)
  File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/gathering.py", line 187, in get_nodes_groups_and_policies
    boundary_policy = _get_policy_by_arn_or_raise(u['PermissionsBoundary']['PermissionsBoundaryArn'],
  File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/gathering.py", line 1005, in _get_policy_by_arn_or_raise
    raise ValueError('Could not locate policy {}.'.format(arn))
ValueError: Could not locate policy arn:aws:iam::aws:policy/<REDACTED>.

To Reproduce
Steps to reproduce the behavior, please include information on suspected users/roles that are the source of the issue when possible:

  1. Create a new IAM User. The user does not need any permissions.
  2. Attach an unused managed-policy as a permission boundary only. When viewing the policy in the Console, under "Policy usage", Permissions should be empty.
  3. Run PMapper

Expected behavior
PMapper successfully completes graphing the environment.

Note
For testing, I changed https://github.com/nccgroup/PMapper/blob/master/principalmapper/graphing/gathering.py#L187 to no longer raise an error if the policy isn't found in the graph data by swapping the function to _get_policy_by_arn (see below).

        if 'PermissionsBoundary' in u:
            boundary_policy = _get_policy_by_arn(u['PermissionsBoundary']['PermissionsBoundaryArn'],
                                                          result['policies'])

I don't know what side-effects this may have, but if this is acceptable, happy to create a PR with the change.

Activity

  1. Techbrunch commented on Sep 19, 2023

    @Techbrunch

    I ran into a similar issue except that the error was raised line 184:

            for p in u['AttachedManagedPolicies']:
                user_policies.append(_get_policy_by_arn_or_raise(p['PolicyArn'], result['policies']))

    The problematic policy is attached as a permissions policy to an IAM user.

    I used the same workaround as @brandonstevens but ran into another issue (not sure if linked):

    # pmapper graph create
    2023-09-19 14:57:32+0000 | Obtaining IAM Users/Roles/Groups/Policies in the account.
    2023-09-19 14:57:56+0000 | Sorting users, roles, groups, policies, and their relationships.
    2023-09-19 14:57:56+0000 | Obtaining Access Keys data for IAM users
    2023-09-19 14:58:40+0000 | Gathering MFA virtual device information
    2023-09-19 14:58:40+0000 | Gathering MFA physical device information
    2023-09-19 14:59:05+0000 | Determining which principals have administrative privileges
    Traceback (most recent call last):
      File "/usr/local/bin/pmapper", line 8, in <module>
        sys.exit(main())
      File "/usr/local/lib/python3.8/site-packages/principalmapper/__main__.py", line 145, in main
        return graph_cli.process_arguments(parsed_args)
      File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/graph_cli.py", line 179, in process_arguments
        graph = graph_actions.create_new_graph(session, service_list, parsed_args.include_regions,
      File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/graph_actions.py", line 39, in create_new_graph
        return gathering.create_graph(session, service_list, region_allow_list, region_deny_list, scps, client_args_map)
      File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/gathering.py", line 81, in create_graph
        update_admin_status(nodes_result, scps)
      File "/usr/local/lib/python3.8/site-packages/principalmapper/graphing/gathering.py", line 782, in update_admin_status
        if query_interface.local_check_authorization_handling_mfa(node, action, node.arn, {},
      File "/usr/local/lib/python3.8/site-packages/principalmapper/querying/query_interface.py", line 208, in local_check_authorization_handling_mfa
        if local_check_authorization_full(principal, action_to_check, resource_to_check, condition_keys_to_check, resource_policy, resource_owner, service_control_policy_groups, session_policy):
      File "/usr/local/lib/python3.8/site-packages/principalmapper/querying/query_interface.py", line 306, in local_check_authorization_full
        if policy_has_matching_statement(policy, 'Deny', action_to_check, resource_to_check, prepped_condition_keys):
      File "/usr/local/lib/python3.8/site-packages/principalmapper/querying/local_policy_simulation.py", line 68, in policy_has_matching_statement
        for statement in _listify_dictionary(base_obj['Statement']):
    TypeError: 'NoneType' object is not subscriptable
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions