Skip to content

Commit

Permalink
Add relative redirect support
Browse files Browse the repository at this point in the history
While loading content, a server can send back a `Location` header that
just includes a URL path, indicating that the same server should be
contacted again, just with a different resource. This was previously
unsupported, so this adds the ability to handle these types of
redirects.
  • Loading branch information
maxburkhardt authored and arkadiyt committed Jan 17, 2018
1 parent 78e640a commit c0009a5
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### 1.0.4 (1/17/2017)
* Handle relative redirects

### 1.0.3 (12/4/2017)
* Use `frozen_string_literal` pragma in all ruby files
* Handle new ruby 2.5 behavior when encountering newlines in header names
Expand Down
2 changes: 2 additions & 0 deletions lib/ssrf_filter/ssrf_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ class CRLFInjection < Error
case response
when ::Net::HTTPRedirection then
url = response['location']
# Handle relative redirects
url = "#{uri.scheme}://#{hostname}:#{uri.port}#{url}" if url.start_with?('/')
else
return response
end
Expand Down
2 changes: 1 addition & 1 deletion lib/ssrf_filter/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class SsrfFilter
VERSION = '1.0.3'.freeze
VERSION = '1.0.4'.freeze
end
15 changes: 15 additions & 0 deletions spec/lib/ssrf_filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -438,5 +438,20 @@ def inject_custom_trust_store(*certificates)
expect(response.code).to eq('200')
expect(response.body).to eq('response body')
end

it 'should follow relative redirects and succeed' do
stub_request(:post, "https://#{public_ipv4}/path?key=value").with(headers: {host: 'www.example.com:443'})
.to_return(status: 301, headers: {location: '/path2?key2=value2'})
stub_request(:post, "https://#{public_ipv4}/path2?key2=value2")
.with(headers: {host: 'www.example.com:443'}).to_return(status: 200, body: 'response body')
resolver = proc do |hostname|
[{
'www.example.com' => public_ipv4
}[hostname]]
end
response = SsrfFilter.post('https://www.example.com/path?key=value', resolver: resolver)
expect(response.code).to eq('200')
expect(response.body).to eq('response body')
end
end
end

0 comments on commit c0009a5

Please sign in to comment.