如何测试Rails视图辅助方法的XSS防护?升级4.2后测试失效
如何在Rails 4.2中正确测试format_entry方法的XSS防护?
你遇到的问题确实是Rails 4.2切换到Nokogiri作为assert_select底层解析器带来的变化——Nokogiri会自动解析HTML实体,所以当你断言div.dataright的文本是AA<BB时,实际Nokogiri解析后得到的文本是AA<BB,自然断言失败。
要正确测试XSS转义是否生效,我们需要验证输出的HTML中包含转义后的实体,而不是验证解析后的文本内容。这里有两种靠谱的解决方式:
方式一:检查元素的原始HTML内容(inner_html)
通过assert_select获取到目标元素后,直接查看它的inner_html属性,这个属性会保留原始的HTML实体,不会被Nokogiri解析:
test 'no xss in format_entry' do label = "LBL" info = "AA<BB" render text: format_entry(label, info) assert_select('div.dataright') do |dataright_divs| assert_equal "AA<BB", dataright_divs.first.inner_html end end
方式二:直接断言渲染后的完整HTML字符串
如果你不需要定位到具体元素,也可以直接检查整个渲染后的HTML是否包含正确的转义内容:
test 'no xss in format_entry' do label = "LBL" info = "AA<BB" rendered_html = render text: format_entry(label, info) assert_match %r{<div class="dataright">AA<BB</div>}, rendered_html end
为什么原来的测试在Rails 4.1中有效?
Rails 4.1及更早版本使用的是Hpricot作为解析器,它在处理assert_select的文本匹配时,不会自动解析HTML实体,所以直接断言转义后的字符串是有效的。但切换到Nokogiri后,解析逻辑发生了变化,就需要调整测试方式了。
另外补充一点:你的format_entry方法其实已经在做正确的XSS防护了——Rails的content_tag会自动对传入的infotext进行HTML转义(除非你用raw()包裹),所以只要确保测试能验证这一点就行。
内容的提问来源于stack exchange,提问作者Meier
相关产品推荐
相关产品推荐

