安全
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 注入一直高居网络安全风险榜的前列,而且至今仍很常见——因为那种不安全的写法(直接把字符串拼起来)恰恰也是最省事的写法。
又称
另见