Preventing Cross-Service Confused Deputy Attacks in AWS Lambda: A Detailed Guide
Using Prowler for Security Compliance
Introduction
In a cloud environment like AWS, the security of services and applications is paramount. One of the common risks associated with Identity and Access Management (IAM) roles is the confused deputy problem. This occurs when one service inadvertently accesses resources on behalf of another service, possibly with more privileges than intended. This article will walk you through the steps to prevent cross-service confused deputy attacks when configuring AWS Lambda and its associated IAM roles using CloudFormation.
How the Prowler warning or severity look like
Ensure IAM Service Roles Prevent Cross-Service Confused Deputy Attacks
Severity: High
Status: FAIL
Region: [Region]
Service: IAM
Finding Information:
Resource ID: [Resource ID]
Resource ARN: arn:aws:iam::[Account ID]:role/[Role Name]
Check ID: iam_role_cross_service_confused_deputy_prevention
Type: Not applicable
Scan Time: [Scan Time]
Prowler Finding ID: [Finding ID]
Common Example for a Blog: Prowler Report Highlighting a Cross-Service Confused Deputy Attack Risk
Ensure IAM Service Roles Prevent Cross-Service Confused Deputy Attacks
Severity: High
Status: FAIL
Region: [Region]
Service: IAM
Finding Information:
Resource ID: [Resource ID]
Resource ARN: arn:aws:iam::[Account ID]:role/[Role Name]
Check ID: iam_role_cross_service_confused_deputy_prevention
Type: Not applicable
Scan Time: [Scan Time]
Prowler Finding ID: [Finding ID]
Details:
The IAM role does not have adequate prevention measures against cross-service confused deputy attacks.
Risk:
This issue could allow unauthorized access to resources by attackers, increasing the risk of privilege escalation or unintended access across AWS services.
Understanding the Confused Deputy Problem
The confused deputy attack is a scenario where a trusted service (the “deputy”) is tricked into performing actions on behalf of another entity. For example, if a Lambda function is configured to assume an IAM role without sufficient restrictions, another service (e.g., AWS CloudFront) may unintentionally use this role to perform unauthorized actions.
In the AWS environment, this is a particularly relevant issue because IAM roles can be used by multiple services, which could lead to unintended access to sensitive resources.
To mitigate this, AWS allows you to set conditions in your IAM policies that restrict access to only certain services and resources using global condition keys like aws:SourceArn
and aws:SourceAccount
.
How Cross-Service Confused Deputy Attacks Occur
Here’s a simplified example:
- Lambda Function with an IAM Role: You create a Lambda function that uses an IAM role to access resources like S3, CloudFront, or CodePipeline.
To fix this, we need to add conditions that restrict which services and resources can assume this role.
Solution: Using aws:SourceArn
and aws:SourceAccount
to Prevent Confused Deputy Attacks
Key Global Condition Context Keys:
aws:SourceAccount
: Ensures that the role can only be assumed by services in a specific AWS account.aws:SourceArn
: Restricts access to specific resources by requiring that the request come from an allowed resource (e.g., a specific Lambda function).
By using these two condition keys, you can drastically reduce the risk of cross-service confused deputy attacks.
Step-by-Step Guide: Configuring Your CloudFormation Template
Here’s how you can prevent confused deputy attacks when configuring an AWS Lambda function with a dedicated IAM role.
1. Define Your Lambda Function
In this example, we’ll create a Lambda function that invalidates cache in AWS CloudFront, which requires permissions to create cache invalidations and interact with other AWS services.
2. Create a Secure IAM Role for the Lambda Function
Next, we’ll create an IAM role with strict conditions that only allow the Lambda function from the same account to assume the role.
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Handler: myHandler.handler
Runtime: nodejs20.x
Tracing: Active
MemorySize: 128
Timeout: 30
CodeUri: myCode/
Description: A Lambda function
Role: !GetAtt MyLambdaIamRole.Arn
Policies:
- Statement:
- Sid: 'cloudfrontCreateValidation'
Effect: Allow
Action:
- cloudfront:CreateInvalidation
Resource: '*'
MyLambdaIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub lambdaIamRole-${AWS::Region}
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Condition:
StringEquals:
aws:SourceAccount: !Ref AWS::AccountId
ArnLike:
aws:SourceArn: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:*
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess
In this setup, the Lambda function is assigned permissions to create CloudFront cache invalidations and manage CodePipeline jobs.
3. Deploy the CloudFormation Template
You can now deploy the CloudFormation template to create the Lambda function and the secured IAM role:
aws cloudformation deploy \
--template-file your-template.yaml \
--stack-name your-stack-name \
--capabilities CAPABILITY_IAM \
--profile your-aws-profile
How the Solution Works
aws:SourceAccount
restricts the role usage to only services within the same AWS account, so no external accounts can access the role.aws:SourceArn
limits the role assumption to specific Lambda function ARNs, ensuring that only the designated function can assume the role.
Together, these two condition keys provide a strong layer of security that prevents unauthorized access from other AWS services or external accounts.
Best Practices for Preventing Confused Deputy Attacks
- Always Use Conditions in IAM Trust Policies: Whenever you’re allowing a service like Lambda, CloudFront, or CodePipeline to assume a role, use the
aws:SourceArn
andaws:SourceAccount
conditions. - Least Privilege Principle: Ensure that IAM policies and roles only allow the minimum permissions necessary for the Lambda function to operate.
- Regular Audits: Regularly review IAM roles and policies for over-permissive trust policies that could expose your environment to confused deputy attacks.
Conclusion
Preventing cross-service confused deputy attacks is crucial to maintaining a secure AWS environment, especially when working with Lambda functions and IAM roles. By applying conditions like aws:SourceArn
and aws:SourceAccount
, you can tightly control which services and resources can assume an IAM role, minimizing the risk of unauthorized access.
By following the steps outlined in this guide, you can safeguard your AWS environment against these types of attacks and ensure that your Lambda functions operate securely.