ScaleSec Blog

PassRole Control | ScaleSec

Written by Dustin Whited | Sep 10, 2020 7:00:00 AM

PassRole Control

iam:PassRole

IAM is the foundation of every cloud deployment. Get it wrong and the blast radius could span services, applications, and even environments. Unfortunately, the necessity to configure it correctly to least privilege comes with the added hardship of the complexity. In this article, we’ll explore the iam:PassRole permission, how it can be restricted, as well as a few preventative and detective controls that can be put in place.

PassRole Problems

Specifying iam:PassRole with Resource: "*" will allow that Principal to pass any role to a service. If an attacker is able to compromise a principal that allows unrestricted iam:PassRole and permissions to create and invoke a Lambda function, they could create a new function, use iam:PassRole to pass an existing overly permissive role, and escalate their privileges. This exact scenario is described by Rhino Security Labs.

Adding to the confusion, iam:PassRole is permission only and not logged by CloudTrail, making it not easily apparent who is passing which roles. Monitoring the actions which require iam:PassRole is the key to detecting abnormal usage.

Which actions require this permission? Actions dependent upon PassRole are documented in the Actions, Resources, and Condition Keys reference documents, but there are instances where it is undocumented. PassRole is not marked as a dependency in the documentation when it is possible to specify an IAM Role, but not explicitly required. For others, it is just not documented. Lambda’s CreateFunction is one such action that requires a Role parameter, yet PassRole is not listed as a dependency.

Restricting PassRole

The good news is that PassRole can be restricted by using resource restrictions and conditionals, but it also presents a few new issues that should be accounted for.

The permission supports restricting by resource just like many other actions. Restricting to a specific role as shown below will narrow the scope, however this requires individual build roles for a pipeline when deploying an application. For some deployment workflows, this could be a significant change.

{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": "arn:aws:iam::123456789012:role/my-special-role"
}]
}

PassRole can also be restricted with the conditionals iam:PassedToService and iam:AssociatedResourceArn.

The statement below implements both conditionals, ensuring that the role can only be passed to the EC2 service, and only for use on instances in the account, in two regions.

{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "ec2.amazonaws.com"
},
"StringLike": {
"iam:AssociatedResourceARN": [
"arn:aws:ec2:us-east-1:123456789012:instance/*",
"arn:aws:ec2:us-west-1:123456789012:instance/*"
]
}
}
}

Of course, in this scenario, the resource may need to be specified before it is created. This works for resources that have user-specified names in the ARN such as Lambdas, but not viable to specify a full ARN that is auto-generated such as an Instance ID.

Looking towards Attribute-based Access Control (ABAC), the passing role is tagged normally or with a session tag. Ensure IAM roles are created with a prefix or path of the tag value. Then, when the session tag of the passing role and prefix of the passed role match, iam:PassRole is allowed.

{
"Effect": "Allow",
"Action": [
"iam:passrole"
],
"Resource": [
"arn:aws:iam::432807222178:role/${aws:PrincipalTag/project}-*"
]
}

Each environment is different and the combination of resource restriction, conditionals, and even ABAC may vary. Implement guardrails that aid in the creation of properly scoped IAM policies and then detect drift.

Prevention and Detection

Create policies that follow the principle of least privilege by leveraging services and controls that help reduce IAM complexity. If a principal is correctly scoped to only the permissions and resources it needs, it limits what an actor can do in the event of a compromise. A well-thought out multi-account strategy in combination with service control policies and boundary permissions also provides guardrails to reduce blast radius and keep developers safe.

Read our post about Making Least Privilege Easier in AWS

No preventative control is complete without a detective counterpart. For finding overly permissive PassRole, there are a number of tools available to investigate policy content in an environment, such as:

Modernizing Security: AWS Series - Analyzing IAM Policies at Scale with Parliament

While they are not explicitly monitoring for PassRole usage, these native services detect abnormal usage patterns and privilege escalation:

As with most scenarios in security, building guardrails around iam:PassRole is an exercise in risk reduction that may employ multiple preventative and detective controls.

Thank you to Allison DiPietro, Jeanier Anderson, and Steven_Adegbenle for their editor contributions.