SAST扫描说我这个JS代码有注入漏洞,该怎么改?

Zz青霞 阅读 35

我在写一个处理用户输入的函数,用字符串拼接SQL查询的时候,SAST工具突然报高危漏洞。代码看起来没问题啊,我明明用了双引号转义……


function buildQuery(input) {
  const query = "SELECT * FROM users WHERE name = "" + input + """;
  return query.replace(/\/g, "\\"); // 我加了转义处理啊!
}

试过用ESLint检查,但没发现语法错误。SAST提示说可能存在SQL注入风险,但后端同事说他们用了参数化查询,前端不用处理?我该改哪里才能让扫描工具不报警呢?

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
技术鑫鑫
你这个代码确实存在SQL注入风险,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库举个例子:
const mysql = require('mysql2');

// 创建连接池
const pool = mysql.createPool({
host: 'localhost',
user: 'user',
password: 'password',
database: 'test',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});

// 使用参数化查询
function buildQuery(input) {
// SQL语句里用?占位符
const query = "SELECT * FROM users WHERE name = ?";

// 查询的时候把参数作为数组传进去
return pool.query(query, [input]);
}

参数化查询的工作原理是:数据库驱动会把参数值单独传输,不会和SQL语句拼接。这样攻击者不管输入什么内容,都会被当作参数值处理,不会改变SQL逻辑。

如果你现在确实改不了后端代码,非要前端处理,那至少得用白名单校验输入。比如限制用户名只能输入字母数字下划线:
function buildQuery(input) {
// 限制输入内容
if (!/^[a-zA-Z0-9_]+$/.test(input)) {
throw new Error('Invalid input');
}

// 这里还是建议改用参数化查询
return SELECT * FROM users WHERE name = '${input}';
}

但这种方案还是治标不治本,建议还是用参数化查询。

最后说说SAST报警的问题。SAST工具扫描的是代码结构,它看到你用字符串拼接SQL语句就会报警,这是正常行为。因为你这种写法确实存在风险,不管后端怎么处理都应该在源头解决问题。

所以结论是:修改代码改用参数化查询,这才是解决SQL注入的根本办法。
点赞 4
2026-02-06 22:24
付娟
付娟 Lv1
你这个代码确实存在SQL注入风险,问题出在字符串拼接上。即使后端用了参数化查询,前端也不能完全依赖它。SAST工具报警是对的,因为你的代码逻辑本身就有隐患。

直接改用 encodeURIComponent 或者更安全的方式处理用户输入,但更好的办法是前端只负责传递原始数据,把 SQL 构造这部分完全交给后端来做。比如你可以这样改:

function buildQuery(input) {
// 直接返回未修改的用户输入,让后端处理
return input;
}

// 调用时
const userInput = buildQuery(userInputFromForm);
// 然后通过 API 把 userInput 发送给后端


记得转义或验证用户输入的内容,但别自己手写 SQL 拼接逻辑。你这里的 .replace 根本没起到作用,语法也有问题。如果一定要在前端预处理,可以用正则严格过滤特殊字符,但还是建议让后端全权负责 SQL 构造。

最后提醒一句,永远不要信任任何用户输入,哪怕你觉得已经加了转义。安全问题上多谨慎都不为过!
点赞 5
2026-01-29 19:24