From 97ca63d87d88b4088fb1995b14103d4fe6a5e594 Mon Sep 17 00:00:00 2001 From: Patrick Tulskie Date: Wed, 22 Aug 2018 12:45:30 -0400 Subject: [PATCH] Whitelist http/https schemes [CVE-2018-16471] --- lib/rack/request.rb | 21 +++++++++++++++++---- 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 ac95b1c..3c35671 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 a44e0a7..8025613 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.">')) + request.scheme.should.not.equal 'a.">' + end + should "parse cookies" do req = Rack::Request.new \ Rack::MockRequest.env_for("", "HTTP_COOKIE" => "foo=bar;quux=h&m") -- 2.17.0