Skip to content

Commit 8691a4a

Browse files
folbricht-stripehsbt
authored andcommitted
[rubygems/rubygems] Use IMDSv2 for S3 instance credentials
rubygems/rubygems@fa1c51ef59
1 parent 9c0ebff commit 8691a4a

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

lib/rubygems/s3_uri_signer.rb

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,20 @@ def ec2_metadata_credentials_json
146146
require_relative "request"
147147
require_relative "request/connection_pools"
148148
require "json"
149-
150-
iam_info = ec2_metadata_request(EC2_IAM_INFO)
149+
token = ec2_metadata_token
150+
iam_info = ec2_metadata_request(EC2_IAM_INFO, token)
151151
# Expected format: arn:aws:iam::<id>:instance-profile/<role_name>
152152
role_name = iam_info["InstanceProfileArn"].split("/").last
153-
ec2_metadata_request(EC2_IAM_SECURITY_CREDENTIALS + role_name)
153+
ec2_metadata_request(EC2_IAM_SECURITY_CREDENTIALS + role_name, token)
154154
end
155155

156-
def ec2_metadata_request(url)
156+
def ec2_metadata_request(url, token)
157157
uri = Gem::URI(url)
158158
@request_pool ||= create_request_pool(uri)
159159
request = Gem::Request.new(uri, Gem::Net::HTTP::Get, nil, @request_pool)
160-
response = request.fetch
160+
response = request.fetch do |req|
161+
req.add_field "X-aws-ec2-metadata-token", token
162+
end
161163

162164
case response
163165
when Gem::Net::HTTPOK then
@@ -167,13 +169,30 @@ def ec2_metadata_request(url)
167169
end
168170
end
169171

172+
def ec2_metadata_token
173+
uri = Gem::URI(EC2_IAM_TOKEN)
174+
@request_pool ||= create_request_pool(uri)
175+
request = Gem::Request.new(uri, Gem::Net::HTTP::Put, nil, @request_pool)
176+
response = request.fetch do |req|
177+
req.add_field "X-aws-ec2-metadata-token-ttl-seconds", 60
178+
end
179+
180+
case response
181+
when Gem::Net::HTTPOK then
182+
response.body
183+
else
184+
raise InstanceProfileError.new("Unable to fetch AWS metadata from #{uri}: #{response.message} #{response.code}")
185+
end
186+
end
187+
170188
def create_request_pool(uri)
171189
proxy_uri = Gem::Request.proxy_uri(Gem::Request.get_proxy_from_env(uri.scheme))
172190
certs = Gem::Request.get_cert_files
173191
Gem::Request::ConnectionPools.new(proxy_uri, certs).pool_for(uri)
174192
end
175193

176194
BASE64_URI_TRANSLATE = { "+" => "%2B", "/" => "%2F", "=" => "%3D", "\n" => "" }.freeze
195+
EC2_IAM_TOKEN = "http://169.254.169.254/latest/api/token"
177196
EC2_IAM_INFO = "http://169.254.169.254/latest/meta-data/iam/info"
178197
EC2_IAM_SECURITY_CREDENTIALS = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
179198
end

0 commit comments

Comments
 (0)