1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
# frozen_string_literal: true
require 'test_helper'
module SecurityFilter
def add_one(input)
"#{input} + 1"
end
end
class SecurityTest < Minitest::Test
include Liquid
def setup
@assigns = {}
end
def test_no_instance_eval
text = %( {{ '1+1' | instance_eval }} )
expected = %( 1+1 )
assert_equal(expected, Template.parse(text).render!(@assigns))
end
def test_no_existing_instance_eval
text = %( {{ '1+1' | __instance_eval__ }} )
expected = %( 1+1 )
assert_equal(expected, Template.parse(text).render!(@assigns))
end
def test_no_instance_eval_after_mixing_in_new_filter
text = %( {{ '1+1' | instance_eval }} )
expected = %( 1+1 )
assert_equal(expected, Template.parse(text).render!(@assigns))
end
def test_no_instance_eval_later_in_chain
text = %( {{ '1+1' | add_one | instance_eval }} )
expected = %( 1+1 + 1 )
assert_equal(expected, Template.parse(text).render!(@assigns, filters: SecurityFilter))
end
def test_does_not_permanently_add_filters_to_symbol_table
current_symbols = Symbol.all_symbols
# MRI imprecisely marks objects found on the C stack, which can result
# in uninitialized memory being marked. This can even result in the test failing
# deterministically for a given compilation of ruby. Using a separate thread will
# keep these writes of the symbol pointer on a separate stack that will be garbage
# collected after Thread#join.
Thread.new do
test = %( {{ "some_string" | a_bad_filter }} )
Template.parse(test).render!
nil
end.join
GC.start
assert_equal([], (Symbol.all_symbols - current_symbols))
end
def test_does_not_add_drop_methods_to_symbol_table
current_symbols = Symbol.all_symbols
assigns = { 'drop' => Drop.new }
assert_equal("", Template.parse("{{ drop.custom_method_1 }}", assigns).render!)
assert_equal("", Template.parse("{{ drop.custom_method_2 }}", assigns).render!)
assert_equal("", Template.parse("{{ drop.custom_method_3 }}", assigns).render!)
assert_equal([], (Symbol.all_symbols - current_symbols))
end
def test_max_depth_nested_blocks_does_not_raise_exception
depth = Liquid::Block::MAX_DEPTH
code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
assert_equal("rendered", Template.parse(code).render!)
end
def test_more_than_max_depth_nested_blocks_raises_exception
depth = Liquid::Block::MAX_DEPTH + 1
code = "{% if true %}" * depth + "rendered" + "{% endif %}" * depth
assert_raises(Liquid::StackLevelError) do
Template.parse(code).render!
end
end
end # SecurityTest
|