Why is this an issue?
AWS Identity and Access Management (IAM) is the service that defines access to AWS resources. One of the core components of IAM is the policy
which, when attached to an identity or a resource, defines its permissions. Policies granting permission to an Identity (a User, a Group or Role) are
called identity-based policies. They add the ability to an identity to perform a predefined set of actions on a list of resources.
Here is an example of a policy document defining a limited set of permission that grants a user the ability to manage his own access keys.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::245500951992:user/${aws:username}",
"Effect": "Allow",
"Sid": "AllowManageOwnAccessKeys"
}
]
}
Privilege escalation generally happens when an identity policy gives an identity the ability to grant more privileges than the ones it already has.
Here is another example of a policy document that hides a privilege escalation. It allows an identity to generate a new access key for any user from
the account, including users with high privileges.
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "AllowManageOwnAccessKeys"
}
]
}
Although it looks like it grants a limited set of permissions, this policy would, in practice, give the highest privileges to the identity it’s
attached to.
Privilege escalation is a serious issue as it allows a malicious user to easily escalate to a high privilege identity from a low privilege identity
it took control of.
The example above is just one of many permission escalation vectors. Here is the list of vectors that the rule can detect:
Vector name |
Summary |
Create Policy Version |
Create a new IAM policy and set it as default |
Set Default Policy Version |
Set a different IAM policy version as default |
Create AccessKey |
Create a new access key for any user |
Create Login Profile |
Create a login profile with a password chosen by the attacker |
Update Login Profile |
Update the existing password with one chosen by the attacker |
Attach User Policy |
Attach a permissive IAM policy like "AdministratorAccess" to a user the attacker controls |
Attach Group Policy |
Attach a permissive IAM policy like "AdministratorAccess" to a group containing a user the attacker controls |
Attach Role Policy |
Attach a permissive IAM policy like "AdministratorAccess" to a role that can be assumed by the user the attacker controls |
Put User Policy |
Alter the existing inline IAM policy from a user the attacker controls |
Put Group Policy |
Alter the existing inline IAM policy from a group containing a user that the attacker controls |
Put Role Policy |
Alter an existing inline IAM role policy. The rule will then be assumed by the user that the attacker controls |
Add User to Group |
Add a user that the attacker controls to a group that has a larger range of permissions |
Update Assume Role Policy |
Update a role’s "AssumeRolePolicyDocument" to allow a user the attacker controls to assume it |
EC2 |
Create an EC2 instance that will execute with high privileges |
Lambda Create and Invoke |
Create a Lambda function that will execute with high privileges and invoke it |
Lambda Create and Add Permission |
Create a Lambda function that will execute with high privileges and grant permission to invoke it to a user or a service |
Lambda triggered with an external event |
Create a Lambda function that will execute with high privileges and link it to an external event |
Update Lambda code |
Update the code of a Lambda function executing with high privileges |
CloudFormation |
Create a CloudFormation stack that will execute with high privileges |
Data Pipeline |
Create a Pipeline that will execute with high privileges |
Glue Development Endpoint |
Create a Glue Development Endpoint that will execute with high privileges |
Update Glue Dev Endpoint |
Update the associated SSH key for the Glue endpoint |
The general recommendation to protect against privilege escalation is to restrict the resources to which sensitive permissions are granted. The
first example above is a good demonstration of sensitive permissions being used with a narrow scope of resources and where no privilege escalation is
possible.
Noncompliant code example
This policy allows to update the code of any lambda function. Updating the code of a lambda executing with high privileges will lead to privilege
escalation.
resource "aws_iam_policy" "lambdaUpdatePolicy" {
name = "lambdaUpdatePolicy"
policy =<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:UpdateFunctionCode"
],
"Resource": "*"
}
]
}
EOF
}
Compliant solution
Narrow the policy to only allow to update the code of certain lambda functions.
resource "aws_iam_policy" "lambdaUpdatePolicy" {
name = "lambdaUpdatePolicy"
policy =<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:UpdateFunctionCode"
],
"Resource": "arn:aws:lambda:us-east-2:123456789012:function:my-function:1"
}
]
}
EOF
}
Resources