歡迎光臨
我們一直在努力

SQL Injection 是什麼:從網頁輸入到資料庫查詢

安全提醒:本文僅供防禦學習,案例皆為虛構資料與不可部署片段;測試僅限自有或明確授權環境。

SQL Injection(SQL 注入)不是「資料庫自己被一段神祕字串破解」,而是應用程式把外部資料錯當成 SQL 語法。只要先看懂資料從瀏覽器走到資料庫的路線,後續 UNION、盲注或 Second-order Injection 就不再只是要背的名詞。

SQL Injection 不安全字串拼接與安全參數化查詢的資料流比較
不安全流程會讓資料混入 SQL 結構;參數化查詢則讓模板與資料保持分離。

本篇會學到什麼

  • HTTP 請求、PHP 變數、SQL 驅動程式與資料庫各自負責什麼。
  • 為何字串拼接會讓「資料」改變「指令結構」。
  • 為何 MySQL、SQL Server、PostgreSQL、Oracle 與 SQLite 都可能受影響。
  • 參數化查詢如何建立程式碼與資料的邊界。

必備名詞與心智模型

可以把資料庫想成餐廳廚房。顧客填寫點餐單是「資料」,菜單規則是「指令」。正常情況下,服務生只把顧客填的內容放進菜單指定欄位;若服務生直接把顧客的整句話抄進廚房命令,顧客便可能改寫命令。

  1. 瀏覽器送出 [email protected]
  2. PHP 把它放入 $email
  3. 程式建立查詢。
  4. 驅動程式將查詢送給資料庫。
  5. 資料庫解析 SQL 語法、檢查權限並執行。

信任邊界不只在表單。URL、Cookie、Header、JSON、訊息佇列與先前存入資料庫的文字,都可能成為外部資料。

發生情境與生活化比喻

常見情境包括登入 Email、商品搜尋、訂單編號、日期篩選、排序欄位、後台報表與 API 查詢。問題不在輸入框長什麼樣,而在資料最後是否進入 SQL 字串。即使前端把欄位設成數字,攻擊者也能直接改 HTTP 請求;前端驗證不是安全邊界。

也沒有「不會被注入的資料庫」。SQLite 沒有獨立伺服器,仍會解析應用程式送入的 SQL;Oracle 有 bind variable,使用者若仍拼接動態 SQL,一樣可能出問題。真正的問題是查詢如何建構與應用程式帳號能做什麼。

不安全的原始碼

$email = $_POST['email'] ?? '';
$sql = "SELECT id, email FROM users WHERE email = '" . $email . "'";
$row = $pdo->query($sql)->fetch();

這段程式把單引號、SQL 關鍵字與外部資料放在同一字串。一般姓名 O'Reilly 都可能破壞語法,更不用說刻意設計的輸入。用黑名單刪除單引號會誤傷合法資料,也無法涵蓋編碼、不同語法與所有資料流。

逐步看懂資料如何變成查詢

  1. 輸入值仍只是字元序列。
  2. 字串串接把它放進 SQL 引號之間。
  3. 資料庫收到的是一整段文字,不知道哪部分原本來自使用者。
  4. SQL parser 依語法重新解讀整段文字。
  5. 只要輸入能改變引號或運算式的邊界,查詢意圖就可能被改寫。

重點不是記住某個 payload,而是問:「外部資料抵達 interpreter 前,程式碼與資料是否仍然分開?」

修補後原始碼

$email = $_POST['email'] ?? '';
$statement = $pdo->prepare(
    'SELECT id, email FROM users WHERE email = :email'
);
$statement->execute(['email' => $email]);
$row = $statement->fetch(PDO::FETCH_ASSOC);

查詢模板先固定,:email 只代表一個完整的資料值。驅動程式會把實際 email 以參數傳遞,資料庫不會把參數內容重新當成 SQL 結構。欄位名、表名或 ASC/DESC 通常不能用值參數代替,這些位置要用固定對照表。

如何驗證修補

  • 正常 email 應維持原功能。
  • 包含單引號的合法值不應造成 SQL 錯誤。
  • 任意特殊字元只應作為一個值比對,不應改變回傳筆數或查詢結構。
  • 應用程式回應不顯示資料庫錯誤、表名或堆疊資訊。
  • 資料庫帳號只有此功能所需的最小權限。

開發與維運防禦清單

  • 搜尋所有 SQL 字串串接、模板插值、raw query 與動態 stored procedure。
  • 對值使用參數化;對識別字與排序方向使用允許清單。
  • 不要把 WAF 或輸入黑名單當作主要修補。
  • 正式環境關閉詳細錯誤顯示,但在受控日誌保留事件 ID。
  • 按讀取、寫入與管理功能拆分資料庫權限。

重點整理與下一篇

SQL Injection 的核心是資料越過信任邊界後,被拼進 interpreter 的指令。資料庫品牌不會自動消除這個問題;安全 API、固定查詢結構與最小權限才是關鍵。下一篇會建立全系列共用的虛構商店模型,教你如何讀懂每個非互動式案例。

參考資料與更新日期

更新日期:2026-07-20

贊(0) 贊助
未經允許不得轉載:波波的寂寞世界 » SQL Injection 是什麼:從網頁輸入到資料庫查詢

波波的寂寞世界

Facebook聯繫我們

覺得文章有幫助,歡迎贊助支持本站

感謝你的支持,我會持續整理資安筆記、實務經驗與有價值的技術內容。

贊助本站