mirror of
https://github.com/jnunemaker/httparty
synced 2023-03-27 23:23:07 -04:00
Merge pull request #450 from linrock/fix-basic-auth-header-leak
Don't send basic auth header when redirecting to different hosts
This commit is contained in:
commit
880a2d575c
2 changed files with 56 additions and 1 deletions
|
@ -128,6 +128,7 @@ module HTTParty
|
|||
end
|
||||
|
||||
handle_deflation unless http_method == Net::HTTP::Head
|
||||
handle_host_redirection if response_redirects?
|
||||
handle_response(chunked_body, &block)
|
||||
end
|
||||
|
||||
|
@ -174,7 +175,7 @@ module HTTParty
|
|||
@raw_request.body = body if body
|
||||
@raw_request.body_stream = options[:body_stream] if options[:body_stream]
|
||||
@raw_request.initialize_http_header(options[:headers].to_hash) if options[:headers].respond_to?(:to_hash)
|
||||
@raw_request.basic_auth(username, password) if options[:basic_auth]
|
||||
@raw_request.basic_auth(username, password) if options[:basic_auth] && send_authorization_header?
|
||||
setup_digest_auth if options[:digest_auth]
|
||||
end
|
||||
|
||||
|
@ -312,6 +313,16 @@ module HTTParty
|
|||
end
|
||||
end
|
||||
|
||||
def handle_host_redirection
|
||||
redirect_path = options[:uri_adapter].parse last_response['location']
|
||||
return if redirect_path.relative? || path.host == redirect_path.host
|
||||
@changed_hosts = true
|
||||
end
|
||||
|
||||
def send_authorization_header?
|
||||
!defined?(@changed_hosts)
|
||||
end
|
||||
|
||||
def response_redirects?
|
||||
case last_response
|
||||
when Net::HTTPNotModified # 304
|
||||
|
|
|
@ -1033,6 +1033,50 @@ RSpec.describe HTTParty::Request do
|
|||
end
|
||||
end
|
||||
|
||||
describe "#send_authorization_header?" do
|
||||
context "basic_auth" do
|
||||
before do
|
||||
@credentials = { username: "username", password: "password" }
|
||||
@authorization = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
|
||||
@request.options[:basic_auth] = @credentials
|
||||
@redirect = stub_response("", 302)
|
||||
@ok = stub_response('<hash><foo>bar</foo></hash>', 200)
|
||||
end
|
||||
|
||||
before(:each) do
|
||||
allow(@http).to receive(:request).and_return(@redirect, @ok)
|
||||
end
|
||||
|
||||
it "should not send Authorization header when redirecting to a different host" do
|
||||
@redirect['location'] = 'http://example.com/'
|
||||
@request.perform
|
||||
@request.send(:setup_raw_request)
|
||||
expect(@request.instance_variable_get(:@raw_request)['authorization']).to be_nil
|
||||
end
|
||||
|
||||
it "should send Authorization header when redirecting to a relative path" do
|
||||
@redirect['location'] = '/v3'
|
||||
@request.perform
|
||||
@request.send(:setup_raw_request)
|
||||
expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
|
||||
end
|
||||
|
||||
it "should send Authorization header when redirecting to the same host" do
|
||||
@redirect['location'] = 'http://api.foo.com/v2'
|
||||
@request.perform
|
||||
@request.send(:setup_raw_request)
|
||||
expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
|
||||
end
|
||||
|
||||
it "should send Authorization header when redirecting to a different port on the same host" do
|
||||
@redirect['location'] = 'http://api.foo.com:3000/v3'
|
||||
@request.perform
|
||||
@request.send(:setup_raw_request)
|
||||
expect(@request.instance_variable_get(:@raw_request)['authorization']).to eq(@authorization)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with POST http method" do
|
||||
it "should raise argument error if query is not a hash" do
|
||||
expect {
|
||||
|
|
Loading…
Reference in a new issue