|
|
8ca061 |
From 8a81d04d2588d9c7a898473b431a0dabcab39fbd Mon Sep 17 00:00:00 2001
|
|
|
8ca061 |
From: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
|
|
|
8ca061 |
Date: Thu, 14 Sep 2017 11:37:47 +0000
|
|
|
8ca061 |
Subject: [PATCH] merge revision(s) 59897:
|
|
|
8ca061 |
|
|
|
8ca061 |
lib/webrick/log.rb: sanitize any type of logs
|
|
|
8ca061 |
|
|
|
8ca061 |
It had failed to sanitize some type of exception messages. Reported and
|
|
|
8ca061 |
patched by Yusuke Endoh (mame) at https://hackerone.com/reports/223363
|
|
|
8ca061 |
|
|
|
8ca061 |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@59902 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
8ca061 |
---
|
|
|
8ca061 |
ChangeLog | 7 +++++++
|
|
|
8ca061 |
lib/webrick/httpstatus.rb | 4 ----
|
|
|
8ca061 |
lib/webrick/log.rb | 4 ++--
|
|
|
8ca061 |
test/webrick/test_httpauth.rb | 36 ++++++++++++++++++++++++++++++++++++
|
|
|
8ca061 |
4 files changed, 45 insertions(+), 6 deletions(-)
|
|
|
8ca061 |
|
|
|
8ca061 |
diff --git a/ChangeLog b/ChangeLog
|
|
|
8ca061 |
index a4594f678f8c..7561c35eb705 100644
|
|
|
8ca061 |
--- a/ChangeLog
|
|
|
8ca061 |
+++ b/ChangeLog
|
|
|
8ca061 |
@@ -4,6 +4,13 @@
|
|
|
8ca061 |
protocol list.
|
|
|
8ca061 |
The protocol list from OpenSSL is not null-terminated.
|
|
|
8ca061 |
patched by Kazuki Yamaguchi [Bug #11810] [ruby-core:72082]
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+Thu Sep 14 20:36:54 2017 Yusuke Endoh <mame@ruby-lang.org>
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ lib/webrick/log.rb: sanitize any type of logs
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ It had failed to sanitize some type of exception messages. Reported and
|
|
|
8ca061 |
+ patched by Yusuke Endoh (mame) at https://hackerone.com/reports/223363
|
|
|
8ca061 |
|
|
|
8ca061 |
Thu Sep 14 20:33:52 2017 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|
|
8ca061 |
|
|
|
8ca061 |
diff --git a/lib/webrick/httpstatus.rb b/lib/webrick/httpstatus.rb
|
|
|
8ca061 |
index 7ffda64cf0f9..5dc136f88f70 100644
|
|
|
8ca061 |
--- a/lib/webrick/httpstatus.rb
|
|
|
8ca061 |
+++ b/lib/webrick/httpstatus.rb
|
|
|
8ca061 |
@@ -20,10 +20,6 @@ module HTTPStatus
|
|
|
8ca061 |
##
|
|
|
8ca061 |
# Root of the HTTP status class hierarchy
|
|
|
8ca061 |
class Status < StandardError
|
|
|
8ca061 |
- def initialize(*args) # :nodoc:
|
|
|
8ca061 |
- args[0] = AccessLog.escape(args[0]) unless args.empty?
|
|
|
8ca061 |
- super(*args)
|
|
|
8ca061 |
- end
|
|
|
8ca061 |
class << self
|
|
|
8ca061 |
attr_reader :code, :reason_phrase # :nodoc:
|
|
|
8ca061 |
end
|
|
|
8ca061 |
diff --git a/lib/webrick/log.rb b/lib/webrick/log.rb
|
|
|
8ca061 |
index 41cde4a74084..4f069ac0c549 100644
|
|
|
8ca061 |
--- a/lib/webrick/log.rb
|
|
|
8ca061 |
+++ b/lib/webrick/log.rb
|
|
|
8ca061 |
@@ -117,10 +117,10 @@ def debug?; @level >= DEBUG; end
|
|
|
8ca061 |
# * Otherwise it will return +arg+.inspect.
|
|
|
8ca061 |
def format(arg)
|
|
|
8ca061 |
if arg.is_a?(Exception)
|
|
|
8ca061 |
- "#{arg.class}: #{arg.message}\n\t" <<
|
|
|
8ca061 |
+ "#{arg.class}: #{AccessLog.escape(arg.message)}\n\t" <<
|
|
|
8ca061 |
arg.backtrace.join("\n\t") << "\n"
|
|
|
8ca061 |
elsif arg.respond_to?(:to_str)
|
|
|
8ca061 |
- arg.to_str
|
|
|
8ca061 |
+ AccessLog.escape(arg.to_str)
|
|
|
8ca061 |
else
|
|
|
8ca061 |
arg.inspect
|
|
|
8ca061 |
end
|
|
|
8ca061 |
diff --git a/test/webrick/test_httpauth.rb b/test/webrick/test_httpauth.rb
|
|
|
8ca061 |
index 27c37f36770b..0aebb7a231c7 100644
|
|
|
8ca061 |
--- a/test/webrick/test_httpauth.rb
|
|
|
8ca061 |
+++ b/test/webrick/test_httpauth.rb
|
|
|
8ca061 |
@@ -79,6 +79,43 @@ def test_basic_auth3
|
|
|
8ca061 |
WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
|
|
|
8ca061 |
}
|
|
|
8ca061 |
tmpfile.close(true)
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ def test_bad_username_with_control_characters
|
|
|
8ca061 |
+ log_tester = lambda {|log, access_log|
|
|
|
8ca061 |
+ assert_equal(2, log.length)
|
|
|
8ca061 |
+ assert_match(/ERROR Basic WEBrick's realm: foo\\ebar: the user is not allowed./, log[0])
|
|
|
8ca061 |
+ assert_match(/ERROR WEBrick::HTTPStatus::Unauthorized/, log[1])
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
+ TestWEBrick.start_httpserver_with_log({}, log_tester) {|server, addr, port, log|
|
|
|
8ca061 |
+ realm = "WEBrick's realm"
|
|
|
8ca061 |
+ path = "/basic_auth"
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ Tempfile.open("test_webrick_auth") {|tmpfile|
|
|
|
8ca061 |
+ tmpfile.close
|
|
|
8ca061 |
+ tmp_pass = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
|
|
|
8ca061 |
+ tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
|
|
|
8ca061 |
+ tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
|
|
|
8ca061 |
+ tmp_pass.flush
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ htpasswd = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
|
|
|
8ca061 |
+ users = []
|
|
|
8ca061 |
+ htpasswd.each{|user, pass| users << user }
|
|
|
8ca061 |
+ server.mount_proc(path){|req, res|
|
|
|
8ca061 |
+ auth = WEBrick::HTTPAuth::BasicAuth.new(
|
|
|
8ca061 |
+ :Realm => realm, :UserDB => htpasswd,
|
|
|
8ca061 |
+ :Logger => server.logger
|
|
|
8ca061 |
+ )
|
|
|
8ca061 |
+ auth.authenticate(req, res)
|
|
|
8ca061 |
+ res.body = "hoge"
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
+ http = Net::HTTP.new(addr, port)
|
|
|
8ca061 |
+ g = Net::HTTP::Get.new(path)
|
|
|
8ca061 |
+ g.basic_auth("foo\ebar", "passwd")
|
|
|
8ca061 |
+ http.request(g){|res| assert_not_equal("hoge", res.body, log.call) }
|
|
|
8ca061 |
+ File.unlink tmpfile.path rescue nil
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
end
|
|
|
8ca061 |
|
|
|
8ca061 |
DIGESTRES_ = /
|
|
|
8ca061 |
diff --git a/test/webrick/utils.rb b/test/webrick/utils.rb
|
|
|
8ca061 |
index e1c2344fb1aa..0e94ad34da71 100644
|
|
|
8ca061 |
--- a/test/webrick/utils.rb
|
|
|
8ca061 |
+++ b/test/webrick/utils.rb
|
|
|
8ca061 |
@@ -54,4 +54,43 @@
|
|
|
8ca061 |
def start_httpproxy(config={}, &block)
|
|
|
8ca061 |
start_server(WEBrick::HTTPProxyServer, config, &block)
|
|
|
8ca061 |
end
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ DefaultLogTester = lambda {|log, access_log| assert_equal([], log) }
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ def start_server_with_log(klass, config={}, log_tester=DefaultLogTester, &block)
|
|
|
8ca061 |
+ log_ary = []
|
|
|
8ca061 |
+ access_log_ary = []
|
|
|
8ca061 |
+ log = proc { "webrick log start:\n" + (log_ary+access_log_ary).join.gsub(/^/, " ").chomp + "\nwebrick log end" }
|
|
|
8ca061 |
+ server = klass.new({
|
|
|
8ca061 |
+ :BindAddress => "127.0.0.1", :Port => 0,
|
|
|
8ca061 |
+ :ServerType => Thread,
|
|
|
8ca061 |
+ :Logger => WEBrick::Log.new(log_ary, WEBrick::BasicLog::WARN),
|
|
|
8ca061 |
+ :AccessLog => [[access_log_ary, ""]]
|
|
|
8ca061 |
+ }.update(config))
|
|
|
8ca061 |
+ server_thread = server.start
|
|
|
8ca061 |
+ server_thread2 = Thread.new {
|
|
|
8ca061 |
+ server_thread.join
|
|
|
8ca061 |
+ if log_tester
|
|
|
8ca061 |
+ log_tester.call(log_ary, access_log_ary)
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
+ addr = server.listeners[0].addr
|
|
|
8ca061 |
+ client_thread = Thread.new {
|
|
|
8ca061 |
+ begin
|
|
|
8ca061 |
+ block.yield([server, addr[3], addr[1], log])
|
|
|
8ca061 |
+ ensure
|
|
|
8ca061 |
+ server.shutdown
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
+ }
|
|
|
8ca061 |
+ client_thread.join
|
|
|
8ca061 |
+ server_thread2.join
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ def start_httpserver_with_log(config={}, log_tester=DefaultLogTester, &block)
|
|
|
8ca061 |
+ start_server_with_log(WEBrick::HTTPServer, config, log_tester, &block)
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
+
|
|
|
8ca061 |
+ def start_httpproxy_with_log(config={}, log_tester=DefaultLogTester, &block)
|
|
|
8ca061 |
+ start_server_with_log(WEBrick::HTTPProxyServer, config, log_tester, &block)
|
|
|
8ca061 |
+ end
|
|
|
8ca061 |
end
|