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