diff options
author | Patrick Tulskie <patricktulskie@gmail.com> | 2018-08-22 12:45:30 -0400 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2018-11-05 11:19:16 -0800 |
commit | 97ca63d87d88b4088fb1995b14103d4fe6a5e594 (patch) | |
tree | 9867fceb55df1ecc45cbdc140d182d55aed702aa | |
parent | 7b5054eedfdbd8f7dd5f348b0a02678b64fdd9de (diff) | |
download | rack-97ca63d87d88b4088fb1995b14103d4fe6a5e594.tar.gz |
Whitelist http/https schemes
[CVE-2018-16471]
-rw-r--r-- | lib/rack/request.rb | 21 | ||||
-rw-r--r-- | test/spec_request.rb | 5 |
2 files changed, 22 insertions, 4 deletions
diff --git a/lib/rack/request.rb b/lib/rack/request.rb index ac95b1ca..3c35671c 100644 --- a/lib/rack/request.rb +++ b/lib/rack/request.rb @@ -13,6 +13,8 @@ module Rack # The environment of the request. attr_reader :env + SCHEME_WHITELIST = %w(https http).freeze + def initialize(env) @env = env end @@ -68,10 +70,8 @@ module Rack 'https' elsif @env['HTTP_X_FORWARDED_SSL'] == 'on' 'https' - elsif @env['HTTP_X_FORWARDED_SCHEME'] - @env['HTTP_X_FORWARDED_SCHEME'] - elsif @env['HTTP_X_FORWARDED_PROTO'] - @env['HTTP_X_FORWARDED_PROTO'].split(',')[0] + elsif forwarded_scheme + forwarded_scheme else @env["rack.url_scheme"] end @@ -394,5 +394,18 @@ module Rack s end end + + def forwarded_scheme + scheme_headers = [ + @env['HTTP_X_FORWARDED_SCHEME'], + @env['HTTP_X_FORWARDED_PROTO'].to_s.split(',')[0] + ] + + scheme_headers.each do |header| + return header if SCHEME_WHITELIST.include?(header) + end + + nil + end end end diff --git a/test/spec_request.rb b/test/spec_request.rb index a44e0a71..8025613f 100644 --- a/test/spec_request.rb +++ b/test/spec_request.rb @@ -425,6 +425,11 @@ describe Rack::Request do request.should.be.ssl? end + should "prevent scheme abuse" do + request = Rack::Request.new(Rack::MockRequest.env_for("/", 'HTTP_X_FORWARDED_SCHEME' => 'a."><script>alert(1)</script>')) + request.scheme.should.not.equal 'a."><script>alert(1)</script>' + end + should "parse cookies" do req = Rack::Request.new \ Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m") |