提问人:Arcanus 提问时间:1/30/2022 最后编辑:O. JonesArcanus 更新时间:1/30/2022 访问量:191
如何在变量中扩展 SQL 查询?
How can I extend an SQL query in a variable?
问:
我正在我的数据库上测试可能的SQL注入,并且我正在运行一个简单的函数来获得用户不应该得到的结果。返回值基于 id 是正确的,但是,查询的其余部分将被完全忽略。
我想从数据表中返回所有数据。
我的语法有问题吗?
这是我的实现:
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);
答:
1赞
Joel Coehoorn
1/30/2022
#1
你不能这样做。事实上,无法做到这一点是参数化查询的全部意义所在。它可以防止攻击者为您提供类似输入的字符串。122; DROP Table users;
评论
0赞
Arcanus
1/30/2022
您能否详细说明一下您的答案中究竟参数化的内容?它是内置的吗?如果是这样,那么SQL注入怎么可能呢?
0赞
Joel Coehoorn
1/30/2022
它也被称为“预准备语句”,大多数库(至少是那些值得使用的库)确实具有内置的功能。SQL注入是不可能的,这才是重点。当有人使用原始字符串连接而不是参数化查询功能时,就会发生 SQL 注入。
2赞
O. Jones
1/30/2022
#2
这看起来像带有 npm mysql 驱动程序包的 nodejs Javascript。而且,我猜您的列被定义为 INT 或 BIGINT,而不是某种文本字符串。id
使用该方法是防止 SQL 注入的正确方法。它是参数化的。这意味着 SQL 中的每个参数都由一个占位符表示。的第二个参数是要替换占位符的参数值数组。对于您的用例,驱动程序会生成如下所示的查询。.query()
?
.query()
SELECT * FROM users WHERE id = '122 UNION SELECT * FROM data'
并将其传递给 MySQL 服务器。然后,服务器获取您传递的字符串,并尝试将其解释为数字。由于MySQL中的一个怪癖,它将字符串解释为数字122,因此查找。(MySQL通过寻找前导数字将字符串强制转换为整数。所以给出 123,并给出 0。这可能会令人困惑。其他品牌和型号的 RDBMS 在给定它们期望整数的字符串时会抛出错误。'122 UNION SELECT * FROM data'
WHERE id = 122
123RedLight
Hello
它正确地忽略了字符串的其余部分。
如果你想让你的代码容易受到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
到服务器,并给你你的数据泄漏。
评论
0赞
O. Jones
1/30/2022
为什么SQL注入很危险?有关一些提示,请参阅 haveibeenpwned.com。
0赞
Arcanus
1/30/2022
感谢您非常清晰和详细的解释。刚刚学到了很多东西,谢谢。
评论