72 lines
2.3 KiB
Ruby
72 lines
2.3 KiB
Ruby
#
|
|
# Monkey patch the webrick vulnerability
|
|
#
|
|
|
|
$stderr.puts "[*] WEBrick directory traversal patch loaded"
|
|
|
|
module WEBrick
|
|
module HTTPServlet
|
|
|
|
class FileHandler < AbstractServlet
|
|
|
|
def service(req, res)
|
|
# if this class is mounted on "/" and /~username is requested.
|
|
# we're going to override path informations before invoking service.
|
|
if defined?(Etc) && @options[:UserDir] && req.script_name.empty?
|
|
if %r|^(/~([^/]+))| =~ req.path_info
|
|
script_name, user = $1, $2
|
|
path_info = $'
|
|
begin
|
|
passwd = Etc::getpwnam(user)
|
|
@root = File::join(passwd.dir, @options[:UserDir])
|
|
req.script_name = script_name
|
|
req.path_info = path_info
|
|
rescue
|
|
@logger.debug "#{self.class}#do_GET: getpwnam(#{user}) failed"
|
|
end
|
|
end
|
|
end
|
|
prevent_directory_traversal(req, res)
|
|
super(req, res)
|
|
end
|
|
|
|
private
|
|
|
|
def prevent_directory_traversal(req, res)
|
|
# Preventing directory traversal on DOSISH platforms;
|
|
# Backslashes (0x5c) in path_info are not interpreted as special
|
|
# character in URI notation. So the value of path_info should be
|
|
# normalize before accessing to the filesystem.
|
|
if File::ALT_SEPARATOR
|
|
# File.expand_path removes the trailing path separator.
|
|
# Adding a character is a workaround to save it.
|
|
# File.expand_path("/aaa/") #=> "/aaa"
|
|
# File.expand_path("/aaa/" + "x") #=> "/aaa/x"
|
|
expanded = File.expand_path(req.path_info + "x")
|
|
expanded[-1, 1] = "" # remove trailing "x"
|
|
req.path_info = expanded
|
|
end
|
|
end
|
|
|
|
def check_filename(req, res, name)
|
|
@options[:NondisclosureName].each{|pattern|
|
|
if File.fnmatch("/#{pattern}", name, File::FNM_CASEFOLD)
|
|
@logger.warn("the request refers nondisclosure name `#{name}'.")
|
|
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
|
end
|
|
}
|
|
end
|
|
|
|
def nondisclosure_name?(name)
|
|
@options[:NondisclosureName].each{|pattern|
|
|
if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
|
|
return true
|
|
end
|
|
}
|
|
return false
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|