前兩天在寫代碼的時候,忽然收到警告說項目代碼中存在 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 漏洞在內的多種安全隱患。