Skip to content

Commit 3bc977d

Browse files
authored
Merge pull request excon#675 from excon/fix-header-splitting
fix header splitting bug
2 parents 8e46e28 + 636e706 commit 3bc977d

File tree

4 files changed

+36
-1
lines changed

4 files changed

+36
-1
lines changed

lib/excon/connection.rb

+7-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,13 @@ def request_call(datum)
138138

139139
# add headers to request
140140
datum[:headers].each do |key, values|
141+
if key.to_s.match(/[\r\n]/)
142+
raise Excon::Errors::InvalidHeaderKey.new(key.to_s.inspect + ' contains forbidden "\r" or "\n"')
143+
end
141144
[values].flatten.each do |value|
145+
if value.to_s.match(/[\r\n]/)
146+
raise Excon::Errors::InvalidHeaderValue.new(value.to_s.inspect + ' contains forbidden "\r" or "\n"')
147+
end
142148
request << key.to_s << ': ' << value.to_s << CR_NL
143149
end
144150
end
@@ -185,7 +191,7 @@ def request_call(datum)
185191
end
186192
rescue => error
187193
case error
188-
when Excon::Errors::StubNotFound, Excon::Errors::Timeout
194+
when Excon::Errors::InvalidHeaderKey, Excon::Errors::InvalidHeaderValue, Excon::Errors::StubNotFound, Excon::Errors::Timeout
189195
raise(error)
190196
else
191197
raise_socket_error(error)

lib/excon/error.rb

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ def initialize(socket_error = Excon::Error.new)
4545
end
4646
end
4747

48+
class InvalidHeaderKey < Error; end
49+
class InvalidHeaderValue < Error; end
4850
class Timeout < Error; end
4951
class ResponseParse < Error; end
5052
class ProxyParse < Error; end

tests/bad_tests.rb

+22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,28 @@
22

33
with_server('bad') do
44

5+
tests('header splitting') do
6+
7+
tests('prevents key splitting').raises(Excon::Errors::InvalidHeaderKey) do
8+
connection = Excon.new('http://127.0.0.1:9292')
9+
connection.request(
10+
headers: { "Foo\r\nBar" => "baz" },
11+
method: :get,
12+
path: '/echo'
13+
)
14+
end
15+
16+
tests('prevents value splitting').raises(Excon::Errors::InvalidHeaderValue) do
17+
connection = Excon.new('http://127.0.0.1:9292')
18+
connection.request(
19+
headers: { Foo: "bar\r\nBaz: qux" },
20+
method: :get,
21+
path: '/echo'
22+
)
23+
end
24+
25+
end
26+
527
tests('bad server: causes EOFError') do
628

729
tests('with no content length and no chunking') do

tests/servers/bad.rb

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
module BadServer
66
def receive_data(data)
77
case data
8+
when %r{^GET /echo\s}
9+
send_data "HTTP/1.1 200 OK\r\n"
10+
send_data "\r\n"
11+
send_data data
12+
close_connection(true)
813
when %r{^GET /eof/no_content_length_and_no_chunking\s}
914
send_data "HTTP/1.1 200 OK\r\n"
1015
send_data "\r\n"

0 commit comments

Comments
 (0)