Running confused deputy attacks exploiting the AWS Serverless Application Repository
Early this month at Black Hat USA 2021, researchers from Wiz.io presented a new confused deputy attack that allows an attacker to access data within your AWS account. Using to coarsely set IAM permissions when publishing an application within the AWS Serverless Application Repository (SAR), an attacker can acquire arbitrary data from the S3 bucket that is used for hosting the application's artifacts. In this article, we explain the vulnerability, showcase an actual exploit and explain how to fix the vulnerability in your account. If you are publishing an application using SAR, we recommend double-checking your permissions.
SAR is a platform that allows developers to publish and share SAM applications across AWS accounts. These applications can then be deployed standalone or easily be integrated into existing SAM applications.
Publishing an application to SAR is straightforward. As an author, one has to pack the underlying application code, templates, license, and readme files in a S3 bucket, create an entry in the SAR and attach a policy to the bucket that grants SAR access to the bucket.
The S3 policy allows SAR to read all objects stored in the specified S3 bucket. In their documentation, AWS initially proposed to attach the following IAM policy to the bucket:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "serverlessrepo.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your-bucket-name>/*",
}
]
}
What's the problem with this policy? It does not restrict the account on which's behalf SAR is allowed to access the bucket! While no account other than the owner of the SAR application can actually change the application's setup in SAR, every account can exploit SAR to query objects and data from an S3 bucket with such a BucketPolicy
.
This allows attackers to extract sensitive data like source code, hardcoded credentials, or configuration files that were never meant to be accessible by others. Even worse, if the bucket is used for more than hosting the packed SAR application, which, by the way, is an antipattern itself, attackers can acquire this data too!
Exploiting the Vulnerability
To showcase the exploit, we prepared a SAR application setup of our Serverless-Goat-Java implementation. Serverless-Goat was originally developed in JavaScript by OWASP and is an intentionally vulnerable serverless application. We published Serverless-Goat-Java into the AWS SAR for security training purposes.
With the following template, we deploy an AWS CloudFormation stack with the required bucket and policy to host a SAR app:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
ServerlessGoatPackages:
Type: AWS::S3::Bucket
Properties:
BucketName: "serverless-goat-packages"
ServerlessGoatPackagesPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref ServerlessGoatPackages
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: ServerlessRepoAccess
Action:
- 's3:GetObject'
Effect: Allow
Resource: !Sub "arn:aws:s3:::${ServerlessGoatPackages}/*"
Principal:
Service: "serverlessrepo.amazonaws.com"
Afterward, we pack our Serverless-Goat-Java application, upload it into the newly created bucket, and create a new SAR application in the SAR.
As you can see, the application is bound to the account 028938425188
and can only be modified by it. Let's call the account hosting the vulnerable app Alice
.
To test our exploit, we need another SAR application in a different account on which's behalf we can query objects from our ill-configured bucket. Let's call it account Eve
. For the sake of ease, we just deployed Serverless-Goat-Java again, but to account Eve
:
Let’s see how we can exploit it!
Now that our setup is complete, we can try to use SAR to query data from account Alice
's bucket and set it as a configuration for account Eve
's SAR app.
Therefore, we instruct SAR to set the Readme file of account Eve
's app to an arbitrary file from account Alice
:
Looking again at the app in the SAR, SAR displays the following Readme in account Eve
's app:
Phew, we are evil! 😈 We just stole the authors license file! Let's try another one:
This time around, the acquired information is much more interesting:
Of course, this is only dummy information for the sake of this demonstration. 😊
As you saw, the exploit is very easy once you know about it. The application's ID is public, only the bucket and file names have to be guessed by an attacker. This might sound hard to do!? Well, as we all know, security by obscurity doesn't work too well, so let's strive for a proper fix!
Fixing the Vulnerability
The fix is even more straightforward than the exploit! We need to make sure that our bucket used for hosting the SAR app is only accessible by the account that actually publishes the app.
Therefore, we have to modify our BucketPolicy
to contain a condition
that checks the AWS account which tries to instruct SAR to access the bucket:
SampleBucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
Bucket: !Ref ServerlessGoatPackages
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: ServerlessRepoAccess
Action:
- 's3:GetObject'
Effect: Allow
Resource: !Sub "arn:aws:s3:::${ServerlessGoatPackages}/*"
Principal:
Service: "serverlessrepo.amazonaws.com"
Condition:
StringEquals:
"aws:SourceAccount": "AWS::AccountId"
Indeed, AWS added the new condition expression right after the vulnerability was disclosed to them and updated their documentation accordingly. However, owners of the SAR applications need to update their S3 bucket policies, otherwise the respective AWS accounts remaining vulnerable.
After re-deploying our stack with the fixed policy, we observe the following when trying the exploit again:
Awesome! Now SAR can only modify account Alice
's app on the behalf of account Alice
! 🛡
Note: We changed the policy back after showcasing the fix, so you can try the exploit yourself easily with our SAR application!
Fixing the vulnerability is one thing. But how to find it in the first place?
We develop CodeShield to help developers and security teams finding and
fixing vulnerabilities in cloud-native applications. CodeShield can also help you to find Buckets that are vulnerable to the depicted confused deputy attack in your CloudFormation stacks and template files. Check it out and try CodeShield yourself!
Stay tuned if you are using Terraform or haven't set up your SAR buckets via a CloudFormation stack. We are currently extending CodeShield to be able to scan whole AWS accounts independently of stacks or templates. If you want to get notified when whole account scanning is ready, drop us a mail!
About the Authors
Manuel Benz is co-founder of CodeShield, a novel context-aware cloud security tool focusing on in-depth program analysis of microservice architectures. Prior to the start-up, Manuel worked as a researcher on combinations of static and dynamic program analysis for vulnerability detection at the Secure Software Engineering group at Paderborn University. Manuel is still actively maintaining the Soot static program analysis framework for Java.
Johannes Späth is an AWS Community Builder and a co-founder of CodeShield. Johannes completed his Ph.D. in static program analysis. In his dissertation, he invented a new algorithm for data-flow analysis which allows automated detection of security vulnerabilities.
Top comments (0)