来自sql注入的sql安全查询

问题描述 投票:0回答:1

我有带有准备好的语句和参数化查询的查询。但在 sonarqube 方面仍然失败并给出了查询安全问题。我不知道我的查询中什么不安全

这是代码:

let { keyword } = req.query;
    const first_query = `
      SELECT hs_code, tree_id, CONCAT(hs_code, ' - ', tree_id)
      AS gabungan FROM referensi.v_btbmi_2022 vb
    `;
    const option =
      keyword.length < 1
        ? 'false'
        : '(tree_id ILIKE :keyword OR hs_code ILIKE :keyword)';

    if (keyword.length < 1) {
      res.status(400).json({
        code: "03",
        message: "data inputan tidak ada",
        data: [],
      });
      return;
    }

    const last_query = await db.query(
      first_query + ' WHERE LENGTH(hs_code) > 7 AND ' + option,
      {
        replacements: { keyword: `%${keyword}%` },
        type: db.QueryTypes.SELECT,
      },
    );

我是后端开发的新手,认为这个查询足够安全。如何改进查询使其真正安全并且可以通过sonarqube?

sql postgresql sequelize.js sql-injection
1个回答
0
投票

我相信您展示的代码没有安全漏洞。

我不使用 Sonarqube,但我相信它注意到您的查询的一部分是通过字符串与您的

option
变量连接形成的。它有一个简单的规则,即使用串联格式化 SQL 查询“可能”存在 SQL 注入风险,因此它将此代码标记为有风险。 但是,在您的情况下,您的

option

变量只能是“false”或“(tree_id ILIKE :keyword OR hs_code ILIKE :keyword)”——这两个值在代码中都是明确的,并且不会受到不受信任的输入的影响。所以很安全。

Sonarqube 显然无法理解这一点,因此您可能必须通过避免严格的串联来重组代码以满足 Sonarqube 的要求。

此外,您的代码逻辑似乎是多余的。如果

keyword.length < 1

,则将

option
设置为 false。但在相同的条件下,您会立即返回状态 400。当
option
为 false 时,您的代码永远不会运行查询,因此
option
变量没有任何用途。
我建议尝试这样:

let { keyword } = req.query; if (keyword.length < 1) { res.status(400).json({ code: "03", message: "data inputan tidak ada", data: [], }); return; } const first_query = ` SELECT hs_code, tree_id, CONCAT(hs_code, ' - ', tree_id) AS gabungan FROM referensi.v_btbmi_2022 vb WHERE LENGTH(hs_code) > 7 AND (tree_id ILIKE :keyword OR hs_code ILIKE :keyword) `; const last_query = await db.query(first_query, { replacements: { keyword: `%${keyword}%` }, type: db.QueryTypes.SELECT, }, );

这将完整的 SQL 查询定义为固定字符串,不使用字符串连接进行格式化。

© www.soinside.com 2019 - 2024. All rights reserved.