# frozen_string_literal: false require "webrick" require "minitest/autorun" require "stringio" require "net/http" module WEBrick class TestHTTPResponse < MiniTest::Unit::TestCase class FakeLogger attr_reader :messages def initialize @messages = [] end def warn msg @messages << msg end end attr_reader :config, :logger, :res def setup super @logger = FakeLogger.new @config = Config::HTTP @config[:Logger] = logger @res = HTTPResponse.new config @res.keep_alive = true end def test_prevent_response_splitting_headers_crlf res['X-header'] = "malicious\r\nCookie: hack" io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_prevent_response_splitting_cookie_headers_crlf user_input = "malicious\r\nCookie: hack" res.cookies << WEBrick::Cookie.new('author', user_input) io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_prevent_response_splitting_headers_cr res['X-header'] = "malicious\rCookie: hack" io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_prevent_response_splitting_cookie_headers_cr user_input = "malicious\rCookie: hack" res.cookies << WEBrick::Cookie.new('author', user_input) io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_prevent_response_splitting_headers_lf res['X-header'] = "malicious\nCookie: hack" io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_prevent_response_splitting_cookie_headers_lf user_input = "malicious\nCookie: hack" res.cookies << WEBrick::Cookie.new('author', user_input) io = StringIO.new res.send_response io io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '500', res.code refute_match 'hack', io.string end def test_set_redirect_response_splitting url = "malicious\r\nCookie: hack" assert_raises(URI::InvalidURIError) do res.set_redirect(WEBrick::HTTPStatus::MultipleChoices, url) end end def test_set_redirect_html_injection url = 'http://example.com////?a
' assert_raises(WEBrick::HTTPStatus::MultipleChoices) do res.set_redirect(WEBrick::HTTPStatus::MultipleChoices, url) end res.status = 300 io = StringIO.new res.send_response(io) io.rewind res = Net::HTTPResponse.read_new(Net::BufferedIO.new(io)) assert_equal '300', res.code refute_match(/