summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-03 14:37:52 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-03-03 14:37:52 +0000
commit76efd3551c856a6b359282ae5e02b18295d6cf97 (patch)
tree3c18da8f760e1018212fbb8687cf45883280c78f /lib
parente7daebf21af1fa6002f86527b0e8d6a0f9dcd67c (diff)
merge revision(s) 15677:
* lib/webrick/httpservlet/filehandler.rb: should normalize path separators in path_info to prevent directory traversal attacks on DOSISH platforms. reported by Digital Security Research Group [DSECRG-08-026]. * lib/webrick/httpservlet/filehandler.rb: pathnames which have not to be published should be checked case-insensitively. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_5@15680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/webrick/httpservlet/filehandler.rb21
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/webrick/httpservlet/filehandler.rb b/lib/webrick/httpservlet/filehandler.rb
index 410cc6f9a9..c8278b7b85 100644
--- a/lib/webrick/httpservlet/filehandler.rb
+++ b/lib/webrick/httpservlet/filehandler.rb
@@ -163,6 +163,7 @@ module WEBrick
end
end
end
+ prevent_directory_traversal(req, res)
super(req, res)
end
@@ -198,6 +199,22 @@ module WEBrick
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 exec_handler(req, res)
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
if set_filename(req, res)
@@ -256,7 +273,7 @@ module WEBrick
def check_filename(req, res, name)
@options[:NondisclosureName].each{|pattern|
- if File.fnmatch("/#{pattern}", name)
+ if File.fnmatch("/#{pattern}", name, File::FNM_CASEFOLD)
@logger.warn("the request refers nondisclosure name `#{name}'.")
raise HTTPStatus::NotFound, "`#{req.path}' not found."
end
@@ -310,7 +327,7 @@ module WEBrick
def nondisclosure_name?(name)
@options[:NondisclosureName].each{|pattern|
- if File.fnmatch(pattern, name)
+ if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
return true
end
}