1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Fix StartTLS stripping vulnerability

This fixes CVE-2021-32066.
Reported by Alexandr Savca in <https://hackerone.com/reports/1178562>.
This commit is contained in:
Shugo Maeda 2021-05-11 10:31:27 +09:00 committed by nagachika
parent fc71da2673
commit e2ac25d0eb
2 changed files with 38 additions and 1 deletions

View file

@ -1218,12 +1218,14 @@ module Net
end end
resp = @tagged_responses.delete(tag) resp = @tagged_responses.delete(tag)
case resp.name case resp.name
when /\A(?:OK)\z/ni
return resp
when /\A(?:NO)\z/ni when /\A(?:NO)\z/ni
raise NoResponseError, resp raise NoResponseError, resp
when /\A(?:BAD)\z/ni when /\A(?:BAD)\z/ni
raise BadResponseError, resp raise BadResponseError, resp
else else
return resp raise UnknownResponseError, resp
end end
end end
@ -3719,6 +3721,10 @@ module Net
class ByeResponseError < ResponseError class ByeResponseError < ResponseError
end end
# Error raised upon an unknown response from the server.
class UnknownResponseError < ResponseError
end
RESPONSE_ERRORS = Hash.new(ResponseError) RESPONSE_ERRORS = Hash.new(ResponseError)
RESPONSE_ERRORS["NO"] = NoResponseError RESPONSE_ERRORS["NO"] = NoResponseError
RESPONSE_ERRORS["BAD"] = BadResponseError RESPONSE_ERRORS["BAD"] = BadResponseError

View file

@ -127,6 +127,16 @@ class IMAPTest < Test::Unit::TestCase
imap.disconnect imap.disconnect
end end
end end
def test_starttls_stripping
starttls_stripping_test do |port|
imap = Net::IMAP.new("localhost", :port => port)
assert_raise(Net::IMAP::UnknownResponseError) do
imap.starttls(:ca_file => CA_FILE)
end
imap
end
end
end end
def start_server def start_server
@ -834,6 +844,27 @@ EOF
end end
end end
def starttls_stripping_test
server = create_tcp_server
port = server.addr[1]
start_server do
sock = server.accept
begin
sock.print("* OK test server\r\n")
sock.gets
sock.print("RUBY0001 BUG unhandled command\r\n")
ensure
sock.close
server.close
end
end
begin
imap = yield(port)
ensure
imap.disconnect if imap && !imap.disconnected?
end
end
def create_tcp_server def create_tcp_server
return TCPServer.new(server_addr, 0) return TCPServer.new(server_addr, 0)
end end