1
0
Fork 0
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:
John Nunemaker 2015-12-02 13:29:18 -05:00
commit 880a2d575c
2 changed files with 56 additions and 1 deletions

View file

@ -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

View file

@ -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 {