如何在变量中扩展 SQL 查询?

How can I extend an SQL query in a variable?

我正在我的数据库上测试可能的 SQL 注入,我是 运行 一个简单的函数来获得用户不应该得到的结果。 return 值基于 id 是正确的,但是,查询的其余部分完全被忽略了。

我要return所有数据来自数据table。

我的语法有问题吗?

这是我的实现:

function test(id) {
  db.query("SELECT * FROM users WHERE id = ?", [id], (err, result) => {
    console.log(result[0]);
  });
}

const id = "122 UNION SELECT * FROM data";
test(id);

你不能这样做。事实上,无法做到这一点是参数化查询的 WHOLE POINT。它可以防止攻击者给你一个像 122; DROP Table users; 这样的字符串作为输入。

这看起来像带有 npm mysql 驱动程序包的 nodejs Javascript。而且,我猜你的 id 列被定义为 INT 或 BIGINT,而不是某种文本字符串。

您使用.query()方法的方式是防止SQL注入的正确方法。它是参数化的。这意味着 SQL 中的每个参数都由 ? 占位符表示。 .query() 的第二个参数是用于替换占位符的参数值数组。对于您的用例,驱动程序生成如下所示的查询。

 SELECT * FROM users WHERE id = '122 UNION SELECT * FROM data' 

并将其传递给 MySQL 服务器。服务器然后获取您传递的字符串并尝试将其解释为数字。由于 MySQL 中的一个怪癖,它将您的 '122 UNION SELECT * FROM data' 字符串解释为数字 122,因此查找 WHERE id = 122。 (MySQL 通过查找前导数字将字符串强制转换为整数。因此 123RedLight 给出 123,而 Hello 给出 0。这可能会造成混淆。其他 RDBMS 的品牌和型号在给定时会抛出错误他们期望整数的字符串。)

它正确地忽略了字符串的其余部分。

如果你想让你的代码容易受到 SQL 注入攻击(你 而不是 想要那样做!)你会写

function test(id) {   /* danger: sql injection in next line */
  db.query("SELECT * FROM users WHERE id = " + id, (err, result) => { /* wrong ! */
    console.log(result[0]);
  });
}

这会发送

 SELECT * FROM users WHERE id = 122 UNION SELECT * FROM data

到服务器,把你的数据泄露给你。