Skip to content

Commit

Permalink
Merge pull request #377 from macournoyer/header-injection
Browse files Browse the repository at this point in the history
Fix possible HTTP Response Splitting
  • Loading branch information
macournoyer authored May 20, 2021
2 parents 026285b + 6c58953 commit 0c6d8e2
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lib/thin/headers.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
module Thin
# Raised when an header is not valid
# and the server can not process it.
class InvalidHeader < StandardError; end

# Store HTTP header name-value pairs direcly to a string
# and allow duplicated entries on some names.
class Headers
HEADER_FORMAT = "%s: %s\r\n".freeze
ALLOWED_DUPLICATES = %w(set-cookie set-cookie2 warning www-authenticate).freeze
CR_OR_LF = /[\r\n]/.freeze

def initialize
@sent = {}
Expand All @@ -22,6 +27,8 @@ def []=(key, value)
value.httpdate
when NilClass
return
when CR_OR_LF
raise InvalidHeader, "Header contains CR or LF"
else
value.to_s
end
Expand Down
17 changes: 17 additions & 0 deletions spec/headers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,21 @@
@headers['Modified-At'] = time
expect(@headers.to_s).to include("Modified-At: #{time.httpdate}")
end

it 'should format Integer values correctly' do
@headers['X-Number'] = 32
expect(@headers.to_s).to include("X-Number: 32")
end

it 'should not allow CRLF' do
expect { @headers['Bad'] = "a\r\nSet-Cookie: injected=value" }.to raise_error(InvalidHeader)
end

it 'should not allow CR' do
expect { @headers['Bad'] = "a\rSet-Cookie: injected=value" }.to raise_error(InvalidHeader)
end

it 'should not allow LF' do
expect { @headers['Bad'] = "a\nSet-Cookie: injected=value" }.to raise_error(InvalidHeader)
end
end

0 comments on commit 0c6d8e2

Please sign in to comment.