Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
FileHandler should not be called for files outside the root
FileHandler#matches? should return false for files that are outside the
"root" path.

Conflicts:
	actionpack/lib/action_dispatch/middleware/static.rb

Conflicts:
	actionpack/lib/action_dispatch/middleware/static.rb
	actionpack/test/dispatch/static_test.rb
  • Loading branch information
tenderlove committed Oct 29, 2014
1 parent 53c845c commit 3437f26
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
21 changes: 20 additions & 1 deletion actionpack/lib/action_dispatch/middleware/static.rb
Expand Up @@ -12,7 +12,7 @@ def initialize(root, cache_control)
def match?(path)
path = path.dup

full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(unescape_path(path)))
full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(clean_path_info(unescape_path(path))))
paths = "#{full_path}#{ext}"

matches = Dir[paths]
Expand Down Expand Up @@ -42,6 +42,25 @@ def escape_glob_chars(path)
path.force_encoding('binary') if path.respond_to? :force_encoding
path.gsub(/[*?{}\[\]]/, "\\\\\\&")
end

private

PATH_SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact)

def clean_path_info(path_info)
parts = path_info.split PATH_SEPS

clean = []

parts.each do |part|
next if part.empty? || part == '.'
part == '..' ? clean.pop : clean << part
end

clean.unshift '/' if parts.empty? || parts.first.empty?

::File.join(*clean)
end
end

class Static
Expand Down
18 changes: 18 additions & 0 deletions actionpack/test/dispatch/static_test.rb
Expand Up @@ -140,10 +140,28 @@ class StaticTest < ActiveSupport::TestCase
[200, {"Content-Type" => "text/plain"}, ["Hello, World!"]]
}
App = ActionDispatch::Static.new(DummyApp, "#{FIXTURE_LOAD_PATH}/public", "public, max-age=60")
Root = "#{FIXTURE_LOAD_PATH}/public"

def setup
@app = App
@root = Root
end

include StaticTests

def test_custom_handler_called_when_file_is_outside_root
filename = 'shared.html.erb'
assert File.exist?(File.join(@root, '..', filename))
env = {
"REQUEST_METHOD"=>"GET",
"REQUEST_PATH"=>"/..%2F#{filename}",
"PATH_INFO"=>"/..%2F#{filename}",
"REQUEST_URI"=>"/..%2F#{filename}",
"HTTP_VERSION"=>"HTTP/1.1",
"SERVER_NAME"=>"localhost",
"SERVER_PORT"=>"8080",
"QUERY_STRING"=>""
}
assert_equal(DummyApp.call(nil), @app.call(env))
end
end

0 comments on commit 3437f26

Please sign in to comment.