aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/template
diff options
context:
space:
mode:
authorArthur Neves <arthurnn@gmail.com>2016-02-02 12:34:11 -0500
committerRafael Mendonça França <rafaelmfranca@gmail.com>2016-02-29 15:39:02 -0300
commitaf9b9132f82d1f468836997c716a02f14e61c38c (patch)
tree206e4b89c5486826efdd5223f17a8767e047cc48 /actionpack/lib/action_view/template
parent9892626579d1c62c367e5344a1d1642708340f88 (diff)
downloadrails-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.rb32
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}}"