跳至主要內容
>_ITDITD網站資安平台

名詞解釋

什麼是 SQL injection(SQLi)——能用輸入改寫資料庫命令的漏洞

SQL injection(SQLi)是一種讓使用者的輸入改寫資料庫命令(SQL)含義的漏洞。它會導致資料被讀取、被竄改、被全部刪除。本文用圖解講解原理,並以防禦視角(不公開攻擊手法)介紹真正有效的防禦:佔位符=prepared statement、ORM、最小權限資料庫。

發布於 2026-06-08 更新於 2026-06-08 閱讀時間 1 分鐘

「在搜尋框裡輸入的文字,竟成了資料庫『命令的一部分』」——這就是 SQL injection。本文講解它的原理與可靠的防禦方法(不公開攻擊手法)。

為什麼會發生(原理)

危險的根源在於用字串串接來組裝 SQL 語句。一旦「把輸入直接混進語句裡」,輸入就會越過「值」的邊界,作為「命令」生效。

✗ 字串串接(危險)

把輸入直接拼進語句 → 輸入可能被解釋為命令的一部分

✓ 佔位符(安全)

值作為「資料」傳入 ? / $1 等佔位框 → 始終只是值

用字串串接混入輸入,就會越過「值的邊界」、改變命令的含義。而佔位符能讓值始終只是值。

受害範圍是「那個資料庫連線能做的一切」。一旦能觸及內部資料庫,它就和 RCESSRF 並列,成為大規模外洩的典型入口。

防禦

1

使用佔位符(prepared statement)(最重要)

組裝 SQL 時不使用字串串接。值透過 ? / 具名參數等作為「資料」傳入。僅此一項,就能讓這一類漏洞幾乎消失。

2

交給 ORM/查詢建構器處理

多數 ORM 預設使用佔位符。越少自己寫裸 SQL 就越安全。即便必須寫裸 SQL,也務必參數化。

3

把資料庫使用者設為最小權限

不要給應用用的資料庫使用者多餘的權限(DROP、其他資料表、管理操作)。即使萬一被攻破,也能縮小受害範圍。

4

輸入校驗作為「輔助」

對型別、長度、格式做校驗是有效的,但不要把它單獨當作防禦的主力。它只是佔位符之上的額外加強。

本站觀點:從根本上不再「手工拼裸 SQL」

SQLi 存在已久卻始終消除不掉——原因在於「圖方便,就把輸入混進語句裡」。本站的立場很明確:不製造把值用字串串接放進 SQL 的場景。只要把佔位符或 ORM 設為預設,這個漏洞就會在設計階段從結構上消失。請不要走「靠手動跳脫硬扛」的方向。

盲點:佔位符只能傳「值」

佔位符並非萬能。它能傳的只有 ,而對**資料表名、欄位名、ORDER BY 的方向(升冪/降冪)**這類「查詢的結構」無能為力。

當你想把這部分做成動態的(例如:讓使用者選擇「排序鍵」「篩選欄位」),不要把輸入直接放進 SQL,而應從事先確定的許可清單裡挑出對應的正規名稱。「排序欄位」「過濾欄位」正是那種容易因「以為佔位符已經守住了」而麻痺大意的典型盲點

接下來閱讀

FAQ

QSQL injection 會造成什麼後果?
A

攻擊者可以改變資料庫查詢的含義,讀取本不該看到的資料、竄改資料,最糟時甚至能全部刪除或繞過身分驗證。它是個人資訊大規模外洩的典型原因之一。

Q最可靠的防禦是什麼?
A

就是「用佔位符(prepared statement)傳值」。組裝 SQL 語句時不使用字串串接,值始終作為「資料」透過另一條路徑傳入。這樣輸入就沒有被當作命令解釋的餘地了。多數 ORM 預設就這麼做。

Q對輸入做跳脫就夠了嗎?
A

手動跳脫容易遺漏,不推薦。真正有效的還是佔位符。此外要把資料庫使用者設為最小權限,以備萬一來縮小受害範圍。