This is part 2 in a series of blog posts about a research project I am conducting in my free time on undocumented AWS APIs and their security impacts.
As a part of this research, I found two minor cross-tenant vulnerabilities in AWS App Runner. These vulnerabilities leaked configuration information across tenant boundaries. While they are both minor issues, they further demonstrate that undocumented AWS APIs have lacked the scrutiny of AWS as well as the cloud security community. If you’d like to see a more impactful cross-tenant vulnerability, check out my previous work.
This information has been shared with AWS who has since remediated both issues.
Please note: The disclosure was delayed on my part so as not to conflict with other research.
apprunner:ListVpcConnectorsForAccount
and apprunner:ListObservabilityConfigurationsForAccount
took an AWS account ID as a parameter.While hunting for undocumented APIs in the AWS Console I eventually stumbled into AWS App Runner. App Runner is a managed container service that automatically builds, deploys, and scales container workloads. It simplifies and speeds up the process of deploying applications in containers, removing the need to manage infrastructure or worry about scaling.
While poking around, I found reference to the following action as a part of the AWS App Runner service definition.
"ListVpcConnectorsForAccount": {
"internalonly": true,
"output": {
"shape": "S5s"
},
"input": {
"type": "structure",
"members": {
"AccountId": {},
"NextToken": {},
"MaxResults": {
"type": "integer"
}
}
}
}
This stood out for two reasons, one, it had an internalonly
attribute which piqued my interest. And two, the members
section (which describes the parameters to send) relied on an AccountId
being passed in. What happens if I provide an account ID that I don’t own?
As you can guess based on the fact that I’m writing a blog post about this, the API did not check if the entity calling the action belonged to the account ID that was passed as a parameter. As a result, you could invoke this action and provide ANY account ID.
In the image above you can see that I was able to list VPC Connectors for the account starting with 009
even though I was invoking it with the account starting with 068
. This would leak the security group ID, subnet ID, and VPC connector ARN cross-tenant.
In a very similar story to the previous finding, I also noticed this App Runner API action.
"ListObservabilityConfigurationsForAccount": {
"internalonly": true,
"output": {
"shape": "S4v"
},
"input": {
"type": "structure",
"members": {
"AccountId": {},
"NextToken": {},
"MaxResults": {
"type": "integer"
}
}
}
}
Again it had the internalonly
attribute and only required an AccountId
as a parameter. Again, the API did not validate the calling identity’s account ID, so I could provide any to it as shown below.
This leaked the observability configuration ARN cross-tenant.
The impact of these specific vulnerabilities are minor, only leaking non-critical information across tenant boundaries about security groups, subnet IDs, and their observability configurations.
What I think is more interesting about these findings is that they show that cross-tenant access control is down to checks on individual APIs by each of the AWS service teams. As a result, It is safe to say there are likely many more APIs which behave this way that have not been scrutinized by AWS or the cloud security community.
I’m excited to share more of my research project soon! Thank you for reading.
Thank you to Christophe Tafani-Dereeper for proof-reading this disclosure and to Ryan S/AWS Security Outreach Team for their assistance.