如何通过mysql2库的预编译模式有效防范Node.js异步SQL查询的注入风险?
- 内容介绍
- 文章标签
- 相关推荐
本文共计932个文字,预计阅读时间需要4分钟。
直接结论:
常见错误现象:query("SELECT * FROM users WHERE id = ?", [userId]) 看似安全,但若 userId 是 "1 OR 1=1" 且驱动未开启 permitLocalFileAccess: false 或 MySQL 配置宽松,仍有风险;更危险的是 query(`SELECT * FROM ${tableName}`, ...) —— 这种动态表名根本无法参数化,execute() 也救不了。
-
execute()要求 SQL 字符串里只出现?占位符,不能有模板字符串拼接 - 连接选项必须显式设置
namedPlaceholders: false(默认是false,但显式声明可防误开) - 首次调用
execute()会触发 PREPARE,后续同结构查询复用执行计划,性能略优
动态表名或列名怎么处理才不炸
预编译机制天生不支持参数化表名、列名、排序字段(如 ORDER BY ? 会被当成字符串字面量)。硬塞进去只会查不到数据或报错 ER_PARSE_ERROR。
本文共计932个文字,预计阅读时间需要4分钟。
直接结论:
常见错误现象:query("SELECT * FROM users WHERE id = ?", [userId]) 看似安全,但若 userId 是 "1 OR 1=1" 且驱动未开启 permitLocalFileAccess: false 或 MySQL 配置宽松,仍有风险;更危险的是 query(`SELECT * FROM ${tableName}`, ...) —— 这种动态表名根本无法参数化,execute() 也救不了。
-
execute()要求 SQL 字符串里只出现?占位符,不能有模板字符串拼接 - 连接选项必须显式设置
namedPlaceholders: false(默认是false,但显式声明可防误开) - 首次调用
execute()会触发 PREPARE,后续同结构查询复用执行计划,性能略优
动态表名或列名怎么处理才不炸
预编译机制天生不支持参数化表名、列名、排序字段(如 ORDER BY ? 会被当成字符串字面量)。硬塞进去只会查不到数据或报错 ER_PARSE_ERROR。

