安全
SQL 注入(SQL injection)
/ ESS-cue-ell in-JEK-shun /
SQL 注入(SQL injection)是一種經典攻擊:使用者輸入的不只是資料,還夾帶了額外的資料庫命令,而程式一不留神就把它們執行了。它發生在程式碼把原始的使用者輸入直接拼進 SQL 查詢的時候——於是那段輸入不再是一個名字,而搖身變成了一條指令。
想像一個表單讓你填使用者名稱,並圍繞它拼出一條查詢。你填個正常名字,沒事。但你要是填進一段精心構造的東西,比如 ' OR '1'='1,這條查詢的含義就被悄悄改寫了,也許讓你能以任何人的身分登入、把整張表拖走,甚至直接刪掉。應用本以為這段輸入只是普通文字;資料庫卻把其中一部分當成了命令來讀。
修復之道簡單得令人愉快,而且絕對有效:永遠別把原始輸入拼進查詢。改用「參數化查詢」(也叫預備語句),把 SQL 和值分兩條獨立的通道送過去。這樣一來,值就只會被當作資料——絕不會被當成命令——這套把戲便徹底失效了。
// vulnerable: input glued into the query
"SELECT * FROM users WHERE name = '" + input + "'"
// safe: value sent separately as a parameter
db.query("SELECT * FROM users WHERE name = ?", [input])上:原始輸入變成了 SQL 的一部分。下:用「?」讓那個值只當資料,而非命令。
二十多年來,SQL 注入一直高居網路安全風險榜的前列,而且至今仍很常見——因為那種不安全的寫法(直接把字串拼起來)恰恰也是最省事的寫法。
又稱
另見