diff options
author | Arthur Neves <arthurnn@gmail.com> | 2016-02-02 12:34:11 -0500 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2016-02-29 15:39:02 -0300 |
commit | af9b9132f82d1f468836997c716a02f14e61c38c (patch) | |
tree | 206e4b89c5486826efdd5223f17a8767e047cc48 /actionpack/lib/action_view/template | |
parent | 9892626579d1c62c367e5344a1d1642708340f88 (diff) | |
download | rails-af9b9132f82d1f468836997c716a02f14e61c38c.tar.gz rails-af9b9132f82d1f468836997c716a02f14e61c38c.tar.bz2 rails-af9b9132f82d1f468836997c716a02f14e61c38c.zip |
Complete work on 3.2 for render_data_leak patch.
Render could leak access to external files before this patch.
A previous patch(CVE-2016-0752), attempted to fix this. However the tests
were miss-placed outside the TestCase subclass, so they were not running.
We should allow :file to be outside rails root, but anything else must
be inside the rails view directory.
The implementation has changed a bit though. Now the patch is more
similar with the 4.x series patches.
Now `render 'foo/bar'`, will add a special key in the options
hash, and not use the :file one, so when we look up that file, we
don't set the fallbacks, and only lookup a template, to constraint the
folders that can be accessed.
CVE-2016-2097
Diffstat (limited to 'actionpack/lib/action_view/template')
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index d3a6d1a3b8..bea8c221c3 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -43,7 +43,13 @@ module ActionView # Normalizes the arguments and passes it on to find_template. def find_all(name, prefix=nil, partial=false, details={}, key=nil, locals=[]) cached(key, [name, prefix, partial], details, locals) do - find_templates(name, prefix, partial, details) + find_templates(name, prefix, partial, details, false) + end + end + + def find_all_anywhere(name, prefix, partial=false, details={}, key=nil, locals=[]) + cached(key, [name, prefix, partial], details, locals) do + find_templates(name, prefix, partial, details, true) end end @@ -54,8 +60,8 @@ module ActionView # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. - def find_templates(name, prefix, partial, details) - raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details) method" + def find_templates(name, prefix, partial, details, outside_app_allowed = false) + raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details, outside_app_allowed) method" end # Helpers that builds a path. Useful for building virtual paths. @@ -110,24 +116,21 @@ module ActionView super() end - cattr_accessor :allow_external_files, :instance_reader => false, :instance_writer => false - self.allow_external_files = false + cattr_accessor :instance_reader => false, :instance_writer => false private - def find_templates(name, prefix, partial, details) + def find_templates(name, prefix, partial, details, outside_app_allowed = false) path = Path.build(name, prefix, partial) - query(path, details, details[:formats]) + query(path, details, details[:formats], outside_app_allowed) end - def query(path, details, formats) + def query(path, details, formats, outside_app_allowed) query = build_query(path, details) template_paths = find_template_paths query - unless self.class.allow_external_files - template_paths = reject_files_external_to_app(template_paths) - end + template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed template_paths.map { |template| handler, format = extract_handler_and_format(template, formats) @@ -267,7 +270,12 @@ module ActionView class OptimizedFileSystemResolver < FileSystemResolver #:nodoc: def build_query(path, details) exts = EXTENSIONS.map { |ext| details[ext] } - query = escape_entry(File.join(@path, path)) + + if path.to_s.starts_with? @path.to_s + query = escape_entry(path) + else + query = escape_entry(File.join(@path, path)) + end query + exts.map { |ext| "{#{ext.compact.uniq.map { |e| ".#{e}," }.join}}" |