Rails 實作儲存型 XSS
本篇內容
- 介紹
- 防範機制
- 挖坑給自己跳
介紹
儲存型 XSS 是利用動態網站經常從資料庫撈出資料後產生 HTML 的特性進行駭入,最常見的就是有貼文功能的網站,原本該呈現正常的貼文,但惡意人士將 JavaScript 寫入貼文中,導致其他用戶在觀看其貼文時瀏覽器直接執行該段內容裡的 JavaScript。
防範機制
儲存型 XSS 的駭入程序大致如下:
- 儲存惡意程式碼進資料庫
- 網站以資料庫的資料產生 HTML 傳給用戶
- 用戶的瀏覽器解析 HTML 並執行惡意程式碼
依照上方流程最常見的防護手段在第二步,在 Rails 內建中,會自動將 HTML 裡的特殊字符進行轉義,例如以下變化:
原始字元 | 轉義處理後 |
---|---|
" | " |
& | & |
' | ' |
< | < |
> | > |
如果不相信可以建一個 index.html
並在其放入:
<script>alert("hack!")</script>
和
<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>
輸出結果:
使用 raw
會導致惡意程式碼被執行。