You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js使用${variable}拼接SQL查询的注入风险及解决办法

问题解答

首先明确结论:你当前的代码写法存在明确的SQL注入风险,你对微软官方文档的描述存在误解。

风险原因说明

你贴的微软官方文档里的安全声明,仅适用于使用驱动内置的参数化查询接口传参的场景,你现在直接通过JS模板字符串将变量${userData.plid}、${userId}拼接进SQL语句的做法,完全绕过了驱动的自动安全校验逻辑,等于直接把用户可控的输入拼到执行语句中,一旦输入值被攻击者篡改,即可执行任意恶意SQL语句。

不建议自行做SQL内容sanitize

手动实现SQL内容转义的风险极高,目前存在大量绕过手动转义的技术手段,包括特殊编码绕过、字符集溢出绕过等,自行实现的sanitize逻辑无法覆盖所有攻击场景,会给业务留下长期的安全隐患。

低改造成本的安全方案

你应该是使用Node的mssql库操作SQL Server,该库本身支持极简的参数化查询写法,不需要你手动编写DECLARE定义参数,仅需要两步改造即可:

  1. 将SQL语句中原本拼接变量的位置替换为@参数名占位符
  2. 调用query方法时,第二个参数传入参数键值对对象

示例改造如下:
改造前代码:

let sqlString = `select * from table where userid=${userId}`
let conn = await sql.connect(process.env.DB_CONNSTRING)
let recordset = await conn.query(sqlString)

改造后代码:

// 仅替换变量位置为占位符
let sqlString = `select * from table where userid=@userId`
let conn = await sql.connect(process.env.DB_CONNSTRING)
// 新增第二个参数传参,驱动自动做安全处理
let recordset = await conn.query(sqlString, { userId })

这种写法完全符合你贴的微软官方文档的安全规则,驱动会自动将参数作为预编译语句的输入处理,完全杜绝SQL注入风险。针对你提到的多依赖查询的场景,参数化查询完全不会影响你的执行顺序,你依然可以按原有逻辑用await依次执行各个查询。

整体改造量极小,全局搜索SQL语句中的${即可定位所有需要修改的插值点,50个路由的改造通常半小时内即可完成,远低于你开发、测试自定义sanitize逻辑的成本,安全保障性也高得多。


内容的提问来源于stack exchange,提问作者Pablo Varela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 07:45:05