iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Modern Web

30天一起搞懂Web觀念系列 第 21

[DAY21] 常見網頁安全問題:XSS、CSRF、Clickjacking 是什麼?

  • 分享至 

  • xImage
  •  

今天簡單介紹一下網頁常見的安全問題

XSS(Cross-Site Scripting)跨站腳本攻擊

XSS 是指攻擊者將惡意JavaScript放到網站中,在使用者的瀏覽器上執行,可能竊取敏感資訊、session、或進行釣魚行為

主要分為三種類型:反射型(Reflected)、儲存型(Stored)和基於DOM的(DOM-based),先來一一介紹他們是如何攻擊的


反射型XSS(Reflected)

  • 如何攻擊:

    攻擊者會在URL中嵌入惡意的腳本,誘導使用者點入。當使用者一點擊,就會開始進行一次性攻擊

  • 如何防禦:

    • 對使用者輸入做過濾(sanitize)編碼(escape)
    • 使用HTTP-only Cookie儲存敏感資訊(避免被 JS 直接存取)
    • 設定CSP(Content Security Policy)限制腳本來源

儲存型XSS(Stored)

  • 如何攻擊:

    攻擊者會將惡意的腳本存在網頁的資料庫或留言板、評論區中,在使用者瀏覽頁面時就會自動執行

  • 如何防禦:

    • 伺服器端必須對輸入資料過濾與驗證

    • 輸出到網頁前一定要HTML編碼(escape output),這個意思是如果留言板有輸入一串訊息:

      <script>alert("Attack")</script>

      沒有轉換成純文字,就會把他直接當JS執行,就會跳出一個alert,這樣如果<script></script> 裡面放了惡意的程式碼,就會把這串留言的訊息轉換成JS執行,會跳出alert。而安全的做法就是要對輸入做HTML的escape的純文字轉換,就會把<變成&lt;整個寫起來像這樣 &lt;script&gt;alert(”Attack”)&lt;/script&gt;

    • 使用安全的模板引擎(就會自動把訊息變成escape的純文字,如前端的Vue/React/EJS/Nunjucks…),避免直接把資料拼進HTML


基於DOM的XSS(DOM-based)

  • 如何攻擊:

    攻擊者透過JavaScript操作 DOM(例如用 innerHTMLeval() 等),攻擊者操控 URL 或其他 DOM 中的可控來源

  • 如何防禦

    • 避免使用 innerHTMLdocument.writeeval() 等危險 API
    • 改用 textContentinnerText 或安全的 DOM API
    • 啟用 Trusted Types(瀏覽器安全機制,Chrome、Edge有支援),強制開發者明確指定可接受的 HTML

CSRF(Cross-Site Request Forgery)跨站請求偽造

如何攻擊?

攻擊者透過隱藏的表單或圖片請求,誘導使用者在已登入的狀態下,對目標網站發送惡意請求(例如轉帳、改密碼)

如何防禦?

  • 使用CSRF Token(隨機字串,必須隨每次請求帶上)
  • 在關鍵操作上要求二次驗證(例如輸入密碼 / OTP)
  • 驗證HTTP Referer / Origin,確保請求來自合法來源

Clickjacking(點擊劫持)

如何攻擊?

攻擊者把合法網站嵌在透明的 <iframe> 裡,誘導使用者以為點擊的是按鈕,實際上是在操作另一個網站(例如按下「轉帳」)

如何防禦?

  • 使用 HTTP Header:
    • X-Frame-Options: DENYSAMEORIGIN
    • Content-Security-Policy: frame-ancestors 'self'
  • 在 UI 上加上frame busting script,意思就是如果偵測到自己的頁面被放入iframe,就會自動跳出來,阻止被嵌入iframe

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

CSP 能做到什麼?

  1. 限制 Script 來源
    • 只能執行來自特定網域的 JavaScript
    • 避免外部惡意腳本被注入
  2. 限制其他資源來源
    • 包含圖片(img-src)、字體(font-src)、iframe(frame-src)等
  3. 限制 Inline Script
    • 預設情況下,CSP 會封鎖所有 <script> 內嵌程式碼

    • 若真的需要,可以用 noncehash 來允許特定程式碼執行

      • nonce(number used once,一次性隨機字串)
        • 每次伺服器回應 HTML 時,產生一個隨機字串
        • 在允許的 <script> 上加上這個字串,例如:
      <script nonce="abc123">console.log("安全的 inline script");</script>
      

      CSP Header 要寫:

      Content-Security-Policy: script-src 'self' 'nonce-abc123'
      

      只有帶有 nonce="abc123"<script> 會執行

      • hash(程式碼雜湊值)
        • 如果某段 inline script 是固定的,可以對它的內容算雜湊(SHA256 等)
        • CSP Header 裡加上這個 hash,就只允許這段程式碼執行
      <script>console.log("hello world");</script>
      

      console.log("hello world"); 算 SHA256,得到:

      Content-Security-Policy: script-src 'self' 'sha256-AbCdEfGhIjK...'
      

      瀏覽器只允許這段程式碼跑,其他的 inline script 都會被封鎖


參考資料

https://www.securityverse.tw/index.php/2023/03/30/elementor-632/

https://www.explainthis.io/zh-hant/swe/what-is-csrf

https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/Clickjacking

https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP


上一篇
[DAY20] NoSQL 是什麼?
下一篇
[DAY22] 前端效能怎麼優化?(1)
系列文
30天一起搞懂Web觀念30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言