SAST扫描说我这个JS代码有注入漏洞,该怎么改?
我在写一个处理用户输入的函数,用字符串拼接SQL查询的时候,SAST工具突然报高危漏洞。代码看起来没问题啊,我明明用了双引号转义……
function buildQuery(input) {
const query = "SELECT * FROM users WHERE name = "" + input + """;
return query.replace(/\/g, "\\"); // 我加了转义处理啊!
}
试过用ESLint检查,但没发现语法错误。SAST提示说可能存在SQL注入风险,但后端同事说他们用了参数化查询,前端不用处理?我该改哪里才能让扫描工具不报警呢?
先看这段代码:
const query = "SELECT * FROM users WHERE name = "" + input + """;
这里拼接出来的SQL语句结构是完全暴露的,攻击者只要输入恶意字符串就能篡改查询逻辑。比如用户输入了
"; DROP TABLE users; --这种payload,你的查询就会变成:SELECT * FROM users WHERE name = ""; DROP TABLE users; --"
这样数据库就会执行多条语句,后果很严重。你后面那个replace处理是马后炮,根本解决不了问题。
现在说解决方案,最稳妥的方式是改用参数化查询(也叫预编译语句)。这种方案会把SQL语句和参数分开传输,数据库会严格按照参数类型处理输入,不会被当作SQL代码执行。
用Node.js的mysql2库举个例子:
参数化查询的工作原理是:数据库驱动会把参数值单独传输,不会和SQL语句拼接。这样攻击者不管输入什么内容,都会被当作参数值处理,不会改变SQL逻辑。
如果你现在确实改不了后端代码,非要前端处理,那至少得用白名单校验输入。比如限制用户名只能输入字母数字下划线:
但这种方案还是治标不治本,建议还是用参数化查询。
最后说说SAST报警的问题。SAST工具扫描的是代码结构,它看到你用字符串拼接SQL语句就会报警,这是正常行为。因为你这种写法确实存在风险,不管后端怎么处理都应该在源头解决问题。
所以结论是:修改代码改用参数化查询,这才是解决SQL注入的根本办法。
直接改用
encodeURIComponent或者更安全的方式处理用户输入,但更好的办法是前端只负责传递原始数据,把 SQL 构造这部分完全交给后端来做。比如你可以这样改:记得转义或验证用户输入的内容,但别自己手写 SQL 拼接逻辑。你这里的
.replace根本没起到作用,语法也有问题。如果一定要在前端预处理,可以用正则严格过滤特殊字符,但还是建议让后端全权负责 SQL 构造。最后提醒一句,永远不要信任任何用户输入,哪怕你觉得已经加了转义。安全问题上多谨慎都不为过!