当需要输出用户的 HTML 内容的时候,必须使用 sanitize
方法:
<%= sanitize body %>
sanitize 方法可以设置 tags 和 attributes 白名单:
<%= sanitize body, tags: %w(a), attributes: %w(href) %>
但是 attributes 白名单不安全,根据现在的实现(#issues-27),如果设置了 attributes 参数,就会跳过一些属性过滤,例如协议过滤:
sanitizie '<a href="javascript:alert()">click</a>'
#=> <a>click</a>
sanitizie '<a href="javascript:alert()">click</a>', attributes: %w(href)
#=> <a href="javascript:alert()">click</a>'
设置 config.action_view.sanitized_allowed_attributes
是同样的效果。
解决方法:
sanitize sanitize(body, tags: TAGS_ALLOWED, attributes: ATTRIBUTES_ALLOWED)
。题外话:
其实两年前 @jasl 就提了这个问题,我现在才看懂…… https://ruby-china.org/topics/16633#reply3
新版已经修复了
https://github.com/rails/rails-html-sanitizer/commit/297161e29a3e11186ce4c02bf7defc088bf544d4