AWS iam:PassRole Security and Compliance
What is iam:PassRole?
iam:PassRole
is a permission that can be included in AWS IAM policies. It
is required if you are creating certain types of resources that need
to run as a different role than the the user creating them. A common occurrence of this is
if you have Continuous Integration (CI) creating EC2 instances that need to have
an Instance Profile, or if you use a Lambda function to create AWS resources.
In these cases, you create the resource with one role (probably an administrator
type role), but the resource itself has a different role (a "run time" role).
In order to give the resource the role it needs, you "pass the role" to it
with the PassRole
permission.
The problem with iam:PassRole
is that it's actually incredibly powerful and
can lead to all manner of privilege escalation issues. In that sense then, it
is pretty deceptive, and the unwary can fall for simple statements such as
"add the iam:PassRole
permission to make that work properly" (often seen in
answers to questions on the Internet!). Even AWS itself can give error messages
which hint that you should add iam:PassRole
, but don't give any warnings about
what that might imply.
A Common Mistake
A common mistaken pattern is below. That is, it's an IAM policy to allow a CI user to create EC2 instances. Don't use this policy - it opens up some privilege escalation issues which aren't at all obvious by looking at it!
{
"Sid": "CiEc2PermissionsInsecureDoNotUse",
"Effect": "Allow",
"Action": [
"iam:PassRole",
"ec2:AttachVolume",
"ec2:CreateSnapshot",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:CreateVolume",
"ec2:DeleteSnapshot",
"ec2:DeleteVolume",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeRegions",
"ec2:DescribeSnapshots",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DetachVolume",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceCreditSpecifications"
],
"Resource": "*"
},
This looks safe enough - it's only applied to the CI user/role, and it only allows a relatively small set of EC2 privileges. We know CI can create instances, because that's what we want it to do, and these permissions don't let it (say) make changes to DNS or whatever.
However, this policy will throw up Critical issues with Kics and other compliance tools.
They will complain that you shouldn't use Resource: "*"
with iam:PassRole
.
As we said, don't use this policy!
The reason this is a problem is because Resource: "*"
allows the CI user to
create an instance with far greater permissions
than we intend, and far greater permissions than the CI user has. All the CI user
would need to do is create an EC2 instance with the AdministratorAccess
role
and they have pretty much full access to all of AWS.
A Better Solution
The above policy can be improved considerably as follows:
{
"Sid": "CiEc2RolePermissions",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::123456123456:role/first-server-role",
"arn:aws:iam::123456123456:role/second-server-role"
],
"Condition": {
"StringEquals": {
"iam:PassedToService": [
"ec2.amazonaws.com"
]
}
}
},
{
"Sid": "CiEc2Permissions",
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:CreateSnapshot",
"ec2:CreateTags",
"ec2:DeleteTags",
"ec2:CreateVolume",
"ec2:DeleteSnapshot",
"ec2:DeleteVolume",
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus",
"ec2:DescribeRegions",
"ec2:DescribeSnapshots",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DetachVolume",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceCreditSpecifications"
],
"Resource": "*"
},
Here we've broken the iam:PassRole
out to its own stanza, and have specifically
tied down the roles that can be passed to the EC2 instances with this policy.
It means our CI user can only create instances with the roles we have
specifically allowed, so that means we can control what those instances can do.
Most importantly though, it is now not possible to create an instance with more
permissions than the user creating it.
We could go further here and limit the regions that instances can be created in, or even the size of those instances. These are both useful additions because they limit the financial exposure of any misuse, although less likely to cause Compliance issues as they're not privilege escalation or security per-se.
Conclusions
iam:PassRole
is deceptively simple, yet is actually dangerously powerful.
We've seen a common use-case for iam:PassRole
, and how it can leave an
opportunity for significant privilege escalation security issues. We've also
seen a relatively modest improvement which dramatically reduces the security
risks, whilst still allowing all the access required.
If you need help getting cleaned up for Compliance or just in figuring out how to make AWS work for you, please contact us - we can help you figure out what you need and make it work for you.