AWS IAM Role Restricts Usage


Description

This policy validates that IAM roles in the account are restrictive in what entities may assume them. This can help prevent malicious actors from assuming roles they should not be assuming.

Query · python

import json

from policyuniverse.policy import Policy

BAD_PRINCIPALS = {
    "*",
}


def policy(resource):
    if resource["AssumeRolePolicyDocument"] is None:
        return True

    iam_policy = Policy(json.loads(resource["AssumeRolePolicyDocument"]))

    for statement in iam_policy.statements:
        # Only apply to allow effects
        if statement.effect != "Allow":
            continue

        # Don't apply where there are strong conditions
        if statement.condition_entries:
            continue

        if BAD_PRINCIPALS.intersection(statement.principals):
            return False

    return True

Analyst notes

Assign an appropriate assume role policy to the IAM role.

Raw source AWS IAM Role Restricts Usage · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: policy
Filename: aws_iam_role_restricts_usage.py
PolicyID: "AWS.IAM.Role.RestrictsUsage"
DisplayName: "AWS IAM Role Restricts Usage"
Enabled: true
ResourceTypes:
  - AWS.IAM.Role
Tags:
  - AWS
  - Security, Identity & Compliance
  - PCI
  - Privilege Escalation:Valid Accounts
Reports:
  PCI:
    - 2.2.4
  MITRE ATT&CK:
    - TA0004:T1078
Severity: Medium
Description: >
  This policy validates that IAM roles in the account are restrictive in what entities may assume them. This can help prevent malicious actors from assuming roles they should not be assuming.
Runbook: Assign an appropriate assume role policy to the IAM role.
Reference: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_permissions-to-switch.html
Tests:
  - Name: Role Restricts Usage
    ExpectedResult: true
    Resource:
      {
        "AccountId": "123456789012",
        "Arn": "arn:aws:iam::123456789012:role/example-role",
        "AssumeRolePolicyDocument": '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:root"},"Action":"sts:AssumeRole","Condition":{"Bool":{"aws:MultiFactorAuthPresent":"true"}}}]}',
        "Description": null,
        "Id": "1111",
        "InlinePolicies": null,
        "ManagedPolicyNames": ["example-policy-1", "example-policy-2"],
        "MaxSessionDuration": 3600,
        "Name": "example-role",
        "Path": "/",
        "PermissionsBoundary": null,
        "Region": "global",
        "ResourceId": "arn:aws:iam::123456789012:role/example-role",
        "ResourceType": "AWS.IAM.Role",
        "Tags": null,
        "TimeCreated": "2019-01-01T00:00:00.000Z",
      }
  - Name: Role Does Not Restrict Usage
    ExpectedResult: false
    Resource:
      {
        "AccountId": "123456789012",
        "Arn": "arn:aws:iam::123456789012:role/example-role",
        "AssumeRolePolicyDocument": '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}',
        "Description": null,
        "Id": "1111",
        "InlinePolicies": null,
        "ManagedPolicyNames": ["example-policy-1", "example-policy-2"],
        "MaxSessionDuration": 3600,
        "Name": "example-role",
        "Path": "/",
        "PermissionsBoundary": null,
        "Region": "global",
        "ResourceId": "arn:aws:iam::123456789012:role/example-role",
        "ResourceType": "AWS.IAM.Role",
        "Tags": null,
        "TimeCreated": "2019-01-01T00:00:00.000Z",
      }
  - Name: Role Restrict Usage With Deny Statement
    ExpectedResult: true
    Resource:
      {
        "AccountId": "123456789012",
        "Arn": "arn:aws:iam::123456789012:role/example-role",
        "AssumeRolePolicyDocument": '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}',
        "Description": null,
        "Id": "1111",
        "InlinePolicies": null,
        "ManagedPolicyNames": ["example-policy-1", "example-policy-2"],
        "MaxSessionDuration": 3600,
        "Name": "example-role",
        "Path": "/",
        "PermissionsBoundary": null,
        "Region": "global",
        "ResourceId": "arn:aws:iam::123456789012:role/example-role",
        "ResourceType": "AWS.IAM.Role",
        "Tags": null,
        "TimeCreated": "2019-01-01T00:00:00.000Z",
      }


# ------ paired body: aws_iam_role_restricts_usage.py ------

import json

from policyuniverse.policy import Policy

BAD_PRINCIPALS = {
    "*",
}


def policy(resource):
    if resource["AssumeRolePolicyDocument"] is None:
        return True

    iam_policy = Policy(json.loads(resource["AssumeRolePolicyDocument"]))

    for statement in iam_policy.statements:
        # Only apply to allow effects
        if statement.effect != "Allow":
            continue

        # Don't apply where there are strong conditions
        if statement.condition_entries:
            continue

        if BAD_PRINCIPALS.intersection(statement.principals):
            return False

    return True

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.