Introduction
I’m researching passing verified identity of an AWS user or role for a service and came across an approach that solves it using AWS STS get-caller-identity paired with presigned urls. I found this article about the technique by Bobby Donchev in AWS Lambda invoker identification
During this research, I discovered that Hashicorp Vault and AWS IAM Authenticator experienced a security vulnerability due to this pattern. In this post I summarize the underlying approach and the mitigations that Google’s Project Zero describe.
Use Case
Allow an AWS Lambda to verify the role of the invoker in order to execute commands that depend on knowing the role.
The technique is to presign an STS get-caller-identity API call on the clientside and send that presigned link to the Lambda. The lambda executes the presigned link via an HTTP GET request and validates the output which feeds into additional internal logic.
This technique is used in:
- Hashicorp’s Vault
- AWS Lambda Invoker Identification by Donchev
- AWS IAM Authenticator in Kubernetes
Security Issues
I found documented and addressed security issues in the Github Tracker for AWS IAM Authenticator and the Google Project Zero post describing vulnerabilities in Hashicorp’s Vault product.
Hashicorp Vault’s Issues
The security problems described are:
- Golang’s surprising xml decoding behavior
- Mitigation: require application/json
- Attacker supplied STS domain component of URL can be spoofed
- Mitigation: use known good STS endpoints concatenated with with presigned payload
- Attacker can spoof
Host
header- Mitigation: allow-list certain headers and maintain control of what headers are used for the upstream
GET
- Mitigation: allow-list certain headers and maintain control of what headers are used for the upstream
- Caller can presign various STS actions
- Mitigation: validate that action is
GetCallerIdentity
- Mitigation: validate that action is
The fixes for Vault were allowlist of HTTP headers, restricting requests to the GetCallerIdentity action and stronger validation of the STS response
ref
AWS IAM Authenticator Issues
For aws-iam-authenticator the issues discovered were:
- Regex for host is too lax
- Mitigation: strict set math of known endpoints in regions
- HTTP Client allows redirects
- Mitigation: Disallow redirects in client
- URL.Query() vs ParseQuery: silent drop of invalid params rather than erroring
- Mitigation: use ParseQuery
- Request smuggling in Golang < 1.12
- Mitigation: Build with Golang >= 1.12
Conclusion
When I prototype a service for using STS get-identity-caller via pre-signed links, I’ll keep in mind these security concerns which boil down to following security principles:
- Distrust user content
- Perform strict validations
- Understand and limit behavior of libraries that could expose a wider surface area of attack
With knowing about the existing security constraints, both in specific and in principles involved, I’m confident about the ability to build a system that uses STS presigned get-identity-caller requests safely and pair it with an AWS lambda which has a second layer of IAM defenses for allow-listing a subset of ARN based invokers.