前两天在写代码的时候,忽然收到警告说项目代码中存在 XSS 漏洞,遂当即根据报告的 URL 排查页面代码,虽然很快就修复了,并且一样问题的讨论两年前就有了,看《别用 raw 和 html_safe》,通常来讲相对有经验的同窗也应该都知道这个点,可是仍是以为有必要写出来,再次提醒一下其余小伙伴,避免踩坑。html
其中,在找到的漏洞出现的地方,都存在相似如下这样的 slim 代码:api
input class='xxx' value==params[:account]
问题就出在双等号 ==
上,由于在 slim 跟 ERB 模板(其余模板好比 HAML 之类的就不清楚了)中,双等号实际上是 Rails 的 raw
这个 helper 方法的缩写,参考连接:安全
To insert something verbatim use the raw helper rather than calling html_safe:ruby
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
or, equivalently, use
<%==
:编辑器
<%== @cms.current_template %> <%# inserts @cms.current_template as is %>
也就是说上面的代码等同于:ide
input class='xxx' value=raw(params[:account])
其中 raw
方法在 Rails 文档中的解释是这样子的:工具
This method outputs without escaping a string. Since escaping tags is now default, this can be used when you don't want Rails to automatically escape tags. This is not recommended if the data is coming from the user's input.ui
大概意思就是,这个方法将会跳过对传入的字符串进行标签过滤以及其余处理,直接将字符串输出到 HTML 中。
因此到如今缘由就很清晰了,由于不当心在代码里多加了一个等号,变成了双等号,致使将会直接把用户的输入输出到待渲染的 HTML 中,在不自知的状况下留下了 XSS 漏洞。因而乎,修复方案仅需去掉一个等号便可:this
input class='xxx' value=params[:account]
这样,Rails 就能继续自动过滤输入的 :account
的参数而且自动过滤恶意内容了。code
在查看 raw
方法的文档时,顺便看了其源码,极其简单,只有一行:
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 16 def raw(stringish) stringish.to_s.html_safe end
raw
只是先确保将 stringish
参数转化为字符串,而后调用了 String#html_safe
方法而已。并且在 String#html_safe
的文档中,一样反复强调慎重使用这两个方法:
It will be inserted into HTML with no additional escaping performed. It is your responsibilty to ensure that the string contains no malicious content. This method is equivalent to the
raw
helper in views.
因此,能够总结一下,如下三种写法的代码都是等价的,都是不安全的:
input class='xxx' value==params[:account] input class='xxx' value=raw(params[:account]) input class='xxx' value=params[:account].html_safe
那在切实须要输出包含 HTML 内容好比富文本编辑器编辑的内容时,如何保证安全?
方案很简单,只须要使用文档中推荐的 sanitize
helper 方法:
It is recommended that you use
sanitize
instead of this method(html_safe).(#sanitize)Sanitizes HTML input, stripping all tags and attributes that aren't whitelisted.
或者使用一些其余第三方的 gem 用来作过滤处理。
不要使用双等号缩写的方式,以免其余人(好比项目里的 Rails 新手)在不了解的状况下照着滥用;
尽量不用 raw
helper 或者 String#html_safe
方法,尽量使用 #sanitize
;
多借助工具进行自动扫描,好比 brakeman
,可以快速高效检测出包括 XSS 漏洞在内的多种安全隐患。