Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions lib/vault/api/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: MPL-2.0

require "json"
require "uri"

require_relative "secret"
require_relative "../client"
Expand Down Expand Up @@ -302,7 +303,7 @@ def gcp(role, jwt, path = 'gcp')
# The path to the auth backend to use for the login procedure.
#
# @param [String] name optional
# The named certificate role provided to the login request.
# The named certificate role provided to the login request.
#
# @return [Secret]
def tls(pem = nil, path = 'cert', name: nil)
Expand All @@ -328,9 +329,23 @@ def tls(pem = nil, path = 'cert', name: nil)
#
# @return [String] aws region
def region_from_sts_endpoint(sts_endpoint)
valid_sts_endpoint = %r{https:\/\/sts\.?(.*)\.amazonaws\.com}.match(sts_endpoint)
raise "Unable to parse STS endpoint #{sts_endpoint}" unless valid_sts_endpoint
valid_sts_endpoint[1].empty? ? 'us-east-1' : valid_sts_endpoint[1]
uri = URI.parse(sts_endpoint)

unless uri.is_a?(URI::HTTPS) && uri.userinfo.nil?
raise "Unable to parse STS endpoint #{sts_endpoint}"
end

case uri.host
when "sts.amazonaws.com"
"us-east-1"
when /\Asts\.([a-z0-9-]+)\.amazonaws\.com\z/,
/\Asts\.([a-z0-9-]+)\.amazonaws\.com\.cn\z/
Regexp.last_match(1)
else
raise "Unable to parse STS endpoint #{sts_endpoint}"
end
rescue URI::InvalidURIError
raise "Unable to parse STS endpoint #{sts_endpoint}"
end
end
end
30 changes: 30 additions & 0 deletions spec/unit/auth_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ module Vault
it { is_expected.to eq 'us-gov-west-1' }
end

context 'with a standard regional endpoint' do
let(:sts_endpoint) { "https://sts.us-west-2.amazonaws.com" }
it { is_expected.to eq 'us-west-2' }
end

context 'with no regional endpoint' do
let(:sts_endpoint) { "https://sts.amazonaws.com" }
it { is_expected.to eq 'us-east-1' }
Expand All @@ -33,6 +38,31 @@ module Vault
let(:sts_endpoint) { "https://stsXamazonaws.com" }
it { expect {subject}.to raise_exception(StandardError, "Unable to parse STS endpoint https://stsXamazonaws.com") }
end

context 'with a host suffix attack' do
let(:sts_endpoint) { 'https://sts.amazonaws.com.evil.example' }
it { expect { subject }.to raise_exception(StandardError, 'Unable to parse STS endpoint https://sts.amazonaws.com.evil.example') }
end

context 'with a query string' do
let(:sts_endpoint) { 'https://sts.us-west-2.amazonaws.com?foo=bar' }
it { is_expected.to eq 'us-west-2' }
end

context 'with a non-root path' do
let(:sts_endpoint) { 'https://sts.us-west-2.amazonaws.com/foo' }
it { is_expected.to eq 'us-west-2' }
end

context 'with a non-default port' do
let(:sts_endpoint) { 'https://sts.us-west-2.amazonaws.com:8443' }
it { is_expected.to eq 'us-west-2' }
end

context 'with embedded user info' do
let(:sts_endpoint) { 'https://user:pass@sts.us-west-2.amazonaws.com' }
it { expect { subject }.to raise_exception(StandardError, 'Unable to parse STS endpoint https://user:pass@sts.us-west-2.amazonaws.com') }
end
end
end
end
Loading