Node.js环境下如何编写防注入的PostgreSQL ILIKE安全查询
问题根因
你的代码有两个核心问题导致运行失败,同时存在安全隐患:
- node-postgres(pg)原生采用
$1、$2...格式的序号占位符,不识别你写的?占位符;且你把占位符写在了单引号内部,驱动会将其判定为普通字符串内容,不会执行参数替换逻辑。 - 如果你尝试直接把用户输入拼接到SQL字符串里实现模糊匹配,会直接留下SQL注入漏洞。
正确实现代码
参数化查询的核心是所有用户可控的内容都不能直接拼接进SQL语句字符串,模糊匹配需要的%通配符要和用户输入在参数层拼接,交给驱动做转义处理,代码如下:
// 先对入参做空值兜底,去除首尾多余空格,避免异常值传入查询 const keyword = req.query.name?.trim() || ''; pg_client.query( "SELECT * FROM spotters WHERE last_name ILIKE $1", [`%${keyword}%`] ) .then((sqlResult) => { // 从返回结果中取匹配到的记录数组 const spotterList = sqlResult.rows; // 编写你的后续结果处理逻辑 }) .catch(err => { // 必须加错误捕获,避免查询异常时触发未处理Promise异常导致服务崩溃 console.error('搜索查询执行失败:', err); // 按你的业务逻辑返回错误响应即可 });
安全性说明
- 上述写法完全规避SQL注入风险:用户传入的任何内容(包括
';DROP TABLE spotters;--这类恶意注入字符串)都会被驱动转义为普通的查询参数,不会被解析为SQL指令执行,最终实现的效果和你预期的SELECT * FROM spotters WHERE last_name ilike '%Burns%'完全一致。 - 禁止使用直接拼接SQL的写法,比如
`SELECT * FROM spotters WHERE last_name ilike '%${req.query.name}%'`,这类写法没有任何转义防护,注入风险极高。
可选规则调整
如果你需要不同的匹配规则,只需要调整参数里通配符的位置即可:
- 前缀匹配(姓氏以关键词开头):
`${keyword}%` - 后缀匹配(姓氏以关键词结尾):
`%${keyword}` - 精确不区分大小写匹配:直接传
keyword,不加通配符即可。
内容的提问来源于stack exchange,提问作者Christoffer
相关产品推荐
相关产品推荐

