From a4af412951c6c226a4a39c1b3aac000a183c4e4b Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Mon, 2 Nov 2026 12:57:54 +0900 Subject: [PATCH] Reject CR/LF in the address and port of a proxy CONNECT request The CONNECT request line and its Host field were built from the address and port without the CR/LF check that the other request components get. Reported-by: Christiaan Swiers (https://hackerone.com/cswiers) Co-Authored-By: Claude Mythos 5.1 --- lib/net/http.rb | 6 ++++++ test/net/http/test_https_proxy.rb | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/lib/net/http.rb b/lib/net/http.rb index 82255f2a..150e2277 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1722,6 +1722,12 @@ def connect write_timeout: @write_timeout, continue_timeout: @continue_timeout, debug_output: @debug_output) + if /[\r\n]/.match?("#{conn_address}:#{@port}") + raise ArgumentError, "address and port cannot include CR/LF" + end + if /[\r\n]/.match?(@address) + raise ArgumentError, "address cannot include CR/LF" + end buf = +"CONNECT #{conn_address}:#{@port} HTTP/#{HTTPVersion}\r\n" \ "Host: #{@address}:#{@port}\r\n" if proxy_user diff --git a/test/net/http/test_https_proxy.rb b/test/net/http/test_https_proxy.rb index 237c16e6..d90c3ff6 100644 --- a/test/net/http/test_https_proxy.rb +++ b/test/net/http/test_https_proxy.rb @@ -41,6 +41,24 @@ def test_https_proxy_authentication end + def test_https_proxy_rejects_crlf_in_address + TCPServer.open("127.0.0.1", 0) {|serv| + _, port, _, _ = serv.addr + client_thread = Thread.new { + proxy = Net::HTTP.Proxy("127.0.0.1", port) + http = proxy.new("foo.example.org\r\nX-Injected: 1\r\nbar.example.org", 8000) + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + assert_raise(ArgumentError) { http.start } + } + server_thread = Thread.new { + sock = serv.accept + sock.close + } + assert_join_threads([client_thread, server_thread]) + } + end + def read_fixture(key) File.read(File.expand_path("../fixtures/#{key}", __dir__)) end