Description
A Lambda execution role supplies the permissions that function code uses to access other AWS services. Unnecessary broad permissions such as iam:*, or permissions involved in assuming another role or creating credentials such as sts:AssumeRole and iam:CreateLoginProfile, can increase the damage if the function is compromised.
The operations actually available depend on attached policies, resource scope, conditions, permissions boundaries, and other applicable limits. If a function needs powerful permissions, confirm the operational need and restrict the permitted targets and conditions.
Potential impact
- A compromised function could misuse sensitive IAM actions available to its execution role.
- Depending on effective permissions and other policies, an attacker might create additional credentials or use another role.
- Sharing an overly privileged role across functions can increase the impact of an incident and make permissions harder to manage.
Remediation
- Identify the actions and resources the function actually uses, then remove unnecessary permissions.
- Use an execution role appropriate to the function and restrict resources and conditions where supported.
- Review inline policies, managed policies, permissions boundaries, and other applicable limits together, then test that required functionality still works.
Examples
These Terraform excerpts illustrate the difference between two policies. The Lambda function, execution-role definition, and configuration that associates the function with the role are omitted.
Before
resource "aws_iam_role_policy" "lambda_privileged_policy" {
name = "lambda-privileged-policy"
role = aws_iam_role.lambda_execution_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
"iam:*"
]
Effect = "Allow"
Resource = "*"
}
]
})
}
After
resource "aws_iam_role_policy" "lambda_scoped_policy" {
name = "lambda-scoped-policy"
role = aws_iam_role.lambda_execution_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ec2:Describe*",
"s3:GetObject"
]
Effect = "Allow"
Resource = "*"
}
]
})
}
Explanation:
- Before: The policy allows
iam:*on every resource. Check whether the execution role needs this breadth of access. - After: The policy removes
iam:*, but retainsResource = "*"and broad read permissions. It is not yet a complete least-privilege policy. In particular, restricts3:GetObjectto the object ARNs in the required buckets.