From c37f0e1719bb9eee71dabed15584bd672df7b443 Mon Sep 17 00:00:00 2001 From: antisnatchor Date: Wed, 20 Feb 2013 11:57:37 +0000 Subject: [PATCH] Patched Rack::File to don't reflect the URI path in the page if a file is not found. Official patch is not out yet. --- core/ruby.rb | 3 +++ core/ruby/file.rb | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 core/ruby/file.rb diff --git a/core/ruby.rb b/core/ruby.rb index 7b3b546d2..61a8a0cfc 100644 --- a/core/ruby.rb +++ b/core/ruby.rb @@ -7,6 +7,9 @@ # @note Patching Ruby Security require 'core/ruby/security' +# @note Patching Rack File class to prevent a potential XSS +require 'core/ruby/file.rb' + # @note Patching Ruby require 'core/ruby/module' require 'core/ruby/object' diff --git a/core/ruby/file.rb b/core/ruby/file.rb new file mode 100644 index 000000000..b40161033 --- /dev/null +++ b/core/ruby/file.rb @@ -0,0 +1,44 @@ +require 'time' +require 'rack/utils' +require 'rack/mime' + +module Rack + class File + def _call(env) + unless ALLOWED_VERBS.include? env["REQUEST_METHOD"] + return fail(405, "Method Not Allowed") + end + + @path_info = Utils.unescape(env["PATH_INFO"]) + parts = @path_info.split SEPS + + parts.inject(0) do |depth, part| + case part + when '', '.' + depth + when '..' + return fail(404, "Not Found") if depth - 1 < 0 + depth - 1 + else + depth + 1 + end + end + + @path = F.join(@root, *parts) + + available = begin + F.file?(@path) && F.readable?(@path) + rescue SystemCallError + false + end + + if available + serving(env) + else + # this is the patched line. No need to reflect the URI path, potential XSS + # exploitable if you can bypass the Content-type: text/plain (IE MHTML and tricks like that) + fail(404, "File not found") + end + end + end +end \ No newline at end of file