mirror of
https://github.com/Shopify/liquid.git
synced 2026-10-03 09:05:13 -07:00
Merge pull request #613 from Shopify/taint-context-warning
Add taint warnings to the context rather than the template.
This commit is contained in:
@@ -33,6 +33,10 @@ module Liquid
|
|||||||
@filters = []
|
@filters = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def warnings
|
||||||
|
@warnings ||= []
|
||||||
|
end
|
||||||
|
|
||||||
def strainer
|
def strainer
|
||||||
@strainer ||= Strainer.create(self, @filters)
|
@strainer ||= Strainer.create(self, @filters)
|
||||||
end
|
end
|
||||||
|
|||||||
+12
-7
@@ -74,7 +74,7 @@ module Liquid
|
|||||||
@filters.inject(context.evaluate(@name)) do |output, (filter_name, filter_args, filter_kwargs)|
|
@filters.inject(context.evaluate(@name)) do |output, (filter_name, filter_args, filter_kwargs)|
|
||||||
filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
|
||||||
context.invoke(filter_name, output, *filter_args)
|
context.invoke(filter_name, output, *filter_args)
|
||||||
end.tap{ |obj| taint_check(obj) }
|
end.tap{ |obj| taint_check(context, obj) }
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -106,17 +106,22 @@ module Liquid
|
|||||||
parsed_args
|
parsed_args
|
||||||
end
|
end
|
||||||
|
|
||||||
def taint_check(obj)
|
def taint_check(context, obj)
|
||||||
if obj.tainted?
|
return unless obj.tainted?
|
||||||
|
return if Template.taint_mode == :lax
|
||||||
|
|
||||||
@markup =~ QuotedFragment
|
@markup =~ QuotedFragment
|
||||||
name = Regexp.last_match(0)
|
name = Regexp.last_match(0)
|
||||||
|
|
||||||
|
error = TaintedError.new("variable '#{name}' is tainted and was not escaped")
|
||||||
|
error.line_number = line_number
|
||||||
|
error.template_name = context.template_name
|
||||||
|
|
||||||
case Template.taint_mode
|
case Template.taint_mode
|
||||||
when :warn
|
when :warn
|
||||||
@warnings ||= []
|
context.warnings << error
|
||||||
@warnings << "variable '#{name}' is tainted and was not escaped"
|
|
||||||
when :error
|
when :error
|
||||||
raise TaintedError, "Error - variable '#{name}' is tainted and was not escaped"
|
raise error
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -124,8 +124,10 @@ class DropsTest < Minitest::Test
|
|||||||
def test_rendering_warns_on_tainted_attr
|
def test_rendering_warns_on_tainted_attr
|
||||||
with_taint_mode(:warn) do
|
with_taint_mode(:warn) do
|
||||||
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
tpl = Liquid::Template.parse('{{ product.user_input }}')
|
||||||
tpl.render!('product' => ProductDrop.new)
|
context = Context.new('product' => ProductDrop.new)
|
||||||
assert_match /tainted/, tpl.warnings.first
|
tpl.render!(context)
|
||||||
|
assert_equal [Liquid::TaintedError], context.warnings.map(&:class)
|
||||||
|
assert_equal "variable 'product.user_input' is tainted and was not escaped", context.warnings.first.to_s(false)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user