我试图了解我的问题是什么。也许我不明白连接是如何工作的?在MySQL版本5.5.40-0 + wheezy1中,会发生以下情况:
firstname='something'
salt='123456'
php 中的正常查询是
UPDATE users SET firstname='$name' WHERE id=:uid;
我尝试将SQL注入到名字区域:
'+ (SELECT s FROM (SELECT salt as s FROM users WHERE username='something') AS saltEntry)+'
所以完整查询是
UPDATE users SET firstname=''+ (SELECT s FROM (SELECT salt as s FROM users WHERE username='something') AS saltEntry)+'' WHERE id=:uid;
结果仅在名字区域中12
或123
,但永远不会出现在完整的字符串中。
另外当我输入时:test'+ (SELECT s FROM (SELECT salt as s FROM users WHERE username='something') AS saltEntry)+'
它也只是返回12
或123
作为名字。
但是当我在没有 ' 或 +: 的 SQL 服务器中尝试时: UPDATE users SET firstname= (SELECT s FROM (SELECT salt as s FROM users WHERE username='something') AS saltEntry) WHERE id=:uid;
它将整个盐复制到名字条目中并且它可以工作。
我想知道我做错了什么?
编辑1:好吧,根据@eggyal如果这个MySQl,那么+只是算术运算符。我不能使用Concat()
因为单引号'开头。然后如何将子查询插入到查询中?
回答:@eggyall在评论中。
使用 CONCAT():
您可以使用 concat() 函数连接多个字符串,并将名字和盐作为参数传递以获得所需的结果:
UPDATE users SET firstname= CONCAT(firstname, (SELECT s FROM (SELECT salt as s FROM users WHERE username='something') AS saltEntry)) WHERE id=:uid;
问题是"+"是一个只能应用于数字的运算符。它不连接两个值,而是将它们相加。现在,当您将其应用于字符串时,MySQL首先将字符串转换为数字(始终等于0),并将该值添加到下一个操作数中。因此,您最终总是得到一个等于数字操作数的结果(如果有的话)。
正如您已经想到的,CONCAT是在此处使用的正确选项。
如果您不需要特别需要将选择字符串附加到查询中,我建议您对其进行一些改进,以避免其中有太多嵌套查询。
由于您执行了更新,因此不能具有对同一表进行嵌套查询的结果的值。但是,您可以使用 join,这将使查询变得不那么复杂且更优化。
UPDATE users as original
JOIN users as salts USING(user_id)
SET original.firstname = CONCAT({$first_name},salts.salt)
WHERE salts.username='something'