Rails 實作儲存型 XSS

本篇內容

  • 介紹
  • 防範機制
  • 挖坑給自己跳

介紹

儲存型 XSS 是利用動態網站經常從資料庫撈出資料後產生 HTML 的特性進行駭入,最常見的就是有貼文功能的網站,原本該呈現正常的貼文,但惡意人士將 JavaScript 寫入貼文中,導致其他用戶在觀看其貼文時瀏覽器直接執行該段內容裡的 JavaScript。

防範機制

儲存型 XSS 的駭入程序大致如下:

  1. 儲存惡意程式碼進資料庫
  2. 網站以資料庫的資料產生 HTML 傳給用戶
  3. 用戶的瀏覽器解析 HTML 並執行惡意程式碼

依照上方流程最常見的防護手段在第二步,在 Rails 內建中,會自動將 HTML 裡的特殊字符進行轉義,例如以下變化:

原始字元轉義處理後
""
&&
''
<&lt;
>&gt;

如果不相信可以建一個 index.html 並在其放入:

&lt;script&gt;alert(&quot;hack!&quot;)&lt;/script&gt;

<script>alert("hack!")</script>

比較看看最後出來的會是什麼。

另外一種防範手法是內容安全政策(CSP),做法是在 HTML 的 Head 裡加入以下 Meta:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

此段規定所有的 JavaScript 皆只能從 <script> 中的 src 屬性讀取,內聯的 JavaScript 皆不會被執行。 而 CSP 也可以設定白名單,詳細作法請參考 Content Security Policy (CSP) 筆記

挖坑給自己跳

在 Rails 中,一般都會使用 *.html.erb ,如果想要在該檔案中遷入變數,就會寫成:

<div> <%= post%> </div>

而其中的 <%= %> 就已經有進行轉義處理,因此就算你在其中放入 JavaScript 它也不會執行:

<div> <%= '<script>alert("hack!")</script>'%> </div>

那假如今天閒來無事,可以試試看在前方加入 raw,那麼它就不會轉義了,例如:

<div> <%= raw '<script>alert("hack!")</script>'%> </div>

輸出結果: image

使用 raw 會導致惡意程式碼被執行。

參考資料