Kubernetes AWS IAM Integration Issues

Risk: Low
Local: No
Remote: Yes

Kubernetes: Multiple issues in aws-iam-authenticator Kubernetes AWS IAM integration (https://github.com/kubernetes-sigs/aws-iam-authenticator/) is implemented on top of the sts:GetCallerIdentity AWS API (https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html). A client authenticates by pre-signing a request to the API endpoint and forwarding it to the server as an Auth token. The server decodes the token and forwards the request to the AWS STS server. The server side part of this code is implemented in the Verify method in pkg/token/token.go (https://github.com/kubernetes-sigs/aws-iam-authenticator/blob/master/pkg/token/token.go). Looking at this method there are a couple of issues: 1. Host regexp is too lax: The server needs to ensure that the presigned URL received from the client actually points to a real STS server. Otherwise, the auth mechanism is easy to bypass by pointing the request at an attacker controlled server. aws-iam-authenticator uses `^sts(\\.[a-z1-9\\-]+)?\\.amazonaws\\.com(\\.cn)?$` to enforce that the URL host component points to an STS server. However, this regex is not strict enough and allows requests to a wide range of AWS services. The most interesting one is probably S3, where URLs like sts.s3.amazonaws.com, sts.s3-us-gov-west-1.amazonaws.com or sts.s3-control.cn-north-1.amazonaws.com.cn point at S3 buckets named STS that can be owned by an arbitrary AWS customer. Luckily I was not able to find a simple way to exploit this as S3 does not allow you to host user controlled content on the \"/\" path. If that changes, you can somehow trick the AWS query parser or an additional AWS service with a similar domain scheme launches, this could become exploitable. FWIW I'm also slightly concerned about the complete lack of region isolation here. It seems unexpected to me that the owner of a random amazonaws.com.cn subdomain can login into arbitrary EKS clusters. 2. HTTP client follows redirects: The code uses the standard Golang HTTP client in its default configuration which follows HTTP redirects. This might make 1. easier to exploit if an attacker can find an open redirect issue on a host that matches the hostname regex. 3. URL.Query vs ParseQuery: The function enforces an allowlist of valid query values by iterating through the parameter map returned by URL.Query(). However, Query() silently drops parameters that Go considers invalid. This could become a problem if the AWS URL parser and Go disagree. The ParseQuery() method additionally returns an error if it encounters invalid parameters and should probably be used instead. 4. Request smuggling for Go version < 1.12: Older versions of Golang are vulnerable to request smuggling issues when requesting malformed URLs containing spaces and newlines (https://github.com/golang/go/issues/22907). As Go reuses TCP connections for the default HTTP client, this can be used to bypass most of the request filtering implemented in token.go and potentially to leak parallel request from other clients. Current official releases of aws-iam-authenticator are not built with a vulnerable Go version, but it might be useful to verify if this is a problem for older clusters. (https://amazon-eks.s3.us-west-2.amazonaws.com/ lists a couple of binaries that are affected by this, but I'm not sure if they would still be used somewhere) Credits: Felix Wilhelm of Google Project Zero This bug is subject to a 90 day disclosure deadline. After 90 days elapse, the bug report will become visible to the public. The scheduled disclosure date is 2020-10-13. Disclosure at an earlier date is also possible if agreed upon by all parties Found by: fwilhelm@google.com



Vote for this issue:


Thanks for you vote!


Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.

(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2021, cxsecurity.com


Back to Top