存储过程真能防住SQL注入吗?我这样写安全吗?

UX-米阳 阅读 2

我在用Node.js调用MySQL的存储过程,听说用存储过程能防SQL注入,但我还是有点不放心。比如我这样拼接参数传进去:

CALL getUserInfo(${userId})

会不会有风险?是不是必须用参数化调用才行?之前试过直接拼字符串,结果被同事说有安全隐患。

我来解答 赞 0 收藏
二维码
手机扫码查看
1 条解答
长孙光磊
你这样写不安全,CALL getUserInfo(${userId}) 这种直接拼接的方式跟普通SQL注入没区别,存储过程白写了。

存储过程防注入的原理是:参数在存储过程内部是作为参数传递的,SQL引擎会把它当成数据处理,而不是SQL代码的一部分。但前提是你得用参数化的方式调用它。

你这种写法相当于在SQL字符串里直接插变量,攻击者只要传 1; DROP TABLE users; -- 这样的值,照样注入成功。

正确写法应该是用预处理语句传参,以node-mysql2为例:

// 错误的写法(你现在的)
await connection.execute(CALL getUserInfo(${userId}));

// 正确的写法
await connection.execute('CALL getUserInfo(?)', [userId]);


存储过程本身没问题,但你调用它的方式得对。参数占位符 ? 会让驱动把 userId 当成纯数据传进去,就算里面包含SQL关键字也不会被执行。

另外提醒一下,光靠存储过程也不是万能的。如果你的存储过程内部还在动态拼接SQL(比如用 CONCAT 拼查询条件),那该注入还是注入。最佳实践是:存储过程用参数,应用程序层也用参数化查询,双重保险。
点赞
2026-03-12 20:02