flawopen.com/SQL 注入/Javascript
想象一个只接收取件码的窗口。SQL 注入就是有人在输入框里输入了一段特殊指令,导致系统把所有人的快递信息全倒了出来,因为系统根本没验证输入是不是合法数字。
当未经校验的用户输入被直接拼接到 SQL 查询语句中时,攻击者可以通过输入闭合原有语句并执行未授权指令。在 Node.js 中,模板字符串是最常见的隐蔽注入源头。
2015 年英国电信巨头 TalkTalk 因遗留系统中的 SQL 注入漏洞被黑客窃取 15 万用户隐私,监管机构处以 40 万英镑巨额罚款。
数据来源:英国信息专员办公室 (ICO) 处罚裁决,2016 年。// userId comes straight from request query
async function getUser(pool, userId) {
const query = `SELECT * FROM users
WHERE id = ${userId}`;
const [rows] = await pool.query(query);
return rows[0];
}
// value is passed separately, never inlined
async function getUser(pool, userId) {
const [rows] = await pool.query(
'SELECT * FROM users WHERE id = ?',
[userId]
);
return rows[0];
}
参数化查询将 SQL 骨架与参数数据分开发送给数据库,数据库在执行前已完成语法树解析,用户输入绝不可能被当作 SQL 指令执行。
mysql2 使用 ? 占位符,而 pg (PostgreSQL) 使用 $1, $2。混用会导致语法报错或参数未正确绑定。
普通 $queryRaw 会自动参数化,但一旦使用 $queryRawUnsafe 并拼接字符串,安全防护立刻失效。
攻击者可以直接绕过前端向后端发送任意 HTTP 请求,必须在后端数据库交互层做参数化。
grep -rn "query(\`.*\${" --include="*.js" --include="*.ts" .
npx eslint --rule 'no-template-curly-in-string: error' .
p/javascript ruleset in CI to catch unparameterized database queries automatically.只有使用 ORM 标准查询构造器才安全;使用 raw()、query() 或原生 SQL 逃逸接口时必须手动参数化。