-
Notifications
You must be signed in to change notification settings - Fork 2.8k
aws-java-sdk-core: EC2MetadataClient.java - Adds sending of a User-Ag… #1562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
aws-java-sdk-core: EC2MetadataClient.java - Adds sending of a User-Ag… #1562
Conversation
…ent other than default User-Agent in Java when making requests to metadata service Similar to AWS Golang SDK and now AWS Ruby SDK, send a User-Agent when making requests to metadata for credentials. Golang uses a structure like aws-sdk-go/1.8.19 and now Ruby uses aws-sdk-ruby3/ as of PR aws#1762. PR aws#1445 adds this for python as well. This will enable protection of AWS credentials from Server Side Request Foregery (SSRF) vectors by use of a metadata proxy and rejecting User-Agents that do not meet a regex.
…r requests to metadata service
Can you provide more details on how change this would prevent SSRF? |
@varunnvs92 sure thing! By providing a User-Agent that is predictable, you can build a metadata proxy to put on your instance that inspects the User-Agent sent in the request. If the User-Agent does not match or fit the pattern you are expecting then you can block that request. Right now, there is not a reasonable way to do so since the default User-Agent is With SSRF, the attacker is tricking your application to make the request and if an attacker knows you run in AWS, a common tactic is to pull AWS credentials via SSRF to the metadata service. |
I should add that with a successful SSRF, the request would be coming from the library the application uses for HTTP requests, which if no User-Agent is set would be the same as what the SDK uses currently. |
headers.put("User-Agent", USER_AGENT); | ||
headers.put("Accept", "*/*"); | ||
headers.put("Connection", "keep-alive"); | ||
|
||
return readResource(endpoint, CredentialsEndpointRetryPolicy.NO_RETRY, new HashMap<String, String>()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the third parameter be headers variable created above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch. Will update!
I have made the change internally. It will be included in today's release. |
…her than default User-Agent in Java when making requests to metadata service Similar to AWS Golang SDK and Ruby SDK, send a User-Agent other than the default User-Agent when making requests to the EC2 metadata for credentials. aws/aws-sdk-java#1562 for aws-sdk-java addresses this also. PR aws#1445 for botocore implements this too. This will enable protection of AWS credentials from Server Side Request Forgery (SSRF) vectors by being able to use a metadata proxy to block requests that do not have the right User-Agent set. User-Agent is not controllable by an attacker via SSRF.
…her than default User-Agent in Java when making requests to metadata service Similar to AWS Golang SDK and Ruby SDK, send a User-Agent other than the default User-Agent when making requests to the EC2 metadata for credentials. aws/aws-sdk-java#1562 for aws-sdk-java addresses this also. PR #1445 for botocore implements this too. This will enable protection of AWS credentials from Server Side Request Forgery (SSRF) vectors by being able to use a metadata proxy to block requests that do not have the right User-Agent set. User-Agent is not controllable by an attacker via SSRF.
@willbengtson, @varunnvs92 It looks like this PR was incomplete. When the SDK fetches credentials for from the EC2 metadata service it does so by making two http requests.
This is because the EC2CredentialsFetcher is directly supplying the headers map... aws-sdk-java/aws-java-sdk-core/src/main/java/com/amazonaws/auth/EC2CredentialsFetcher.java Lines 121 to 124 in 9d9bc2f
... and therefor does not get the defaults defined here… aws-sdk-java/aws-java-sdk-core/src/main/java/com/amazonaws/internal/EC2CredentialsUtils.java Lines 81 to 88 in 9d9bc2f
I think it would be better to add the default headers here… aws-sdk-java/aws-java-sdk-core/src/main/java/com/amazonaws/internal/EC2CredentialsUtils.java Lines 110 to 113 in 9d9bc2f
WDYT? |
@muhqu I think this makes sense. Good catch. |
…her than default User-Agent in Java when making requests to metadata service Similar to AWS Golang SDK and Ruby SDK, send a User-Agent other than the default User-Agent when making requests to the EC2 metadata for credentials. aws/aws-sdk-java#1562 for aws-sdk-java addresses this also. PR #1445 for botocore implements this too. This will enable protection of AWS credentials from Server Side Request Forgery (SSRF) vectors by being able to use a metadata proxy to block requests that do not have the right User-Agent set. User-Agent is not controllable by an attacker via SSRF.
Adds the sending of a User-Agent other than default User-Agent in Java when making requests to metadata service
Similar to AWS Golang SDK and now AWS Ruby SDK, send a User-Agent when making requests to metadata for credentials.
Golang uses a structure like aws-sdk-go/1.8.19 and now Ruby uses aws-sdk-ruby3/ as of PR #1762. PR #1445 adds this for python as well.
This will enable protection of AWS credentials from Server Side Request Foregery (SSRF) vectors by use of a metadata proxy and rejecting User-Agents that do not meet a regex.