React里用预编译语句防SQL注入时参数化失败怎么办?
我在React组件里用Axios调用后端查询接口,参数直接拼接到SQL字符串里了,担心SQL注入风险。按照教程改成预编译语句后,参数化一直失败,控制台报错说”参数位置无效”。
这是我的代码片段:
// 用户输入直接拼接到SQL
const rawQuery = <code>SELECT * FROM users WHERE name = '${username}'</code>;
// 尝试改用预编译参数
const safeQuery = <code>SELECT * FROM users WHERE name = ?</code>;
axios.post('/api/query', { sql: safeQuery, values: [username] })
后端是Node.js+mysql模块,按理说应该支持参数化查询。但返回错误提示说参数位置有问题,手动测试时如果把?换成具体值就能成功。是不是React这边参数传递方式有问题?或者预编译语法用错了?
你现在等于在前端拼了个带?的SQL语句发给后端,然后后端如果直接拿这个sql字符串去query,那?根本不会被当作参数占位符,而是字面量,当然报错。
正确做法是:前端正常传参数,别碰SQL:
后端收到请求,用mysql模块的参数化查询,比如用 mysql2:
注意要用 execute 而不是 query,只有 execute 支持预编译参数。query 虽然也能传数组参数,但默认不开启安全模式,容易被绕过。
另外,千万别让前端传SQL语句过来,这是大忌。攻击者随便改个SQL发过去,你后端直接执行,等于开了后门。接口应该定死逻辑,只接受数据,不接受可执行语句。
总结:前端只传数据,后端做参数化查询,中间别传SQL字符串。记得转义这事永远是在数据落地的地方做,不是在前端。