Php 如果页面上只显示一个结果,SQL注入是否不可能?

Php 如果页面上只显示一个结果,SQL注入是否不可能?,php,mysql,security,sql-injection,Php,Mysql,Security,Sql Injection,我在大学里为我的安全模块做了一个SQL注入项目,我试图学习它是如何工作的 我可以看到当脚本不过滤输入,然后在DB结果集上循环,在屏幕上显示数据时,它是如何工作的。但据我所知,以下代码不易受SQL注入的影响,因为它只希望在屏幕上显示一组值: <?php mysql_connect("localhost", "root", ""); mysql_select_db("testdb"); $result = mysql_query("SELECT id, name, description F

我在大学里为我的安全模块做了一个SQL注入项目,我试图学习它是如何工作的

我可以看到当脚本不过滤输入,然后在DB结果集上循环,在屏幕上显示数据时,它是如何工作的。但据我所知,以下代码不易受SQL注入的影响,因为它只希望在屏幕上显示一组值:

<?php
mysql_connect("localhost", "root", "");
mysql_select_db("testdb");

$result = mysql_query("SELECT id, name, description FROM test_table WHERE id = ".$_GET['id']);

list($id, $name, $description) = mysql_fetch_row($result);

echo "ID: $id \n";
echo "Name: $name \n";
echo "Description: $description \n";

?>
查询的UNION部分的值不会显示,除非我运行mysql\u fetch\u row$result语句两次,如下所示:

<?php
$result = mysql_query("SELECT id, name, description FROM test_table WHERE id = ".$_GET['id']);

list($id, $name, $description) = mysql_fetch_row($result);

echo "ID: $id \n";
echo "Name: $name \n";
echo "Description: $description \n";

list($id, $name, $description) = mysql_fetch_row($result);

echo "ID: $id \n";
echo "Name: $name \n";
echo "Description: $description \n";
?>
然后才显示语句的UNION部分的值,即用户名、密码

如果有人知道这方面的一两件事,您能否确认我说的上述代码不受SQL注入的影响是正确的,因为它只希望在屏幕上显示一组值

如果我错了,请纠正我


感谢您的帮助。

SQL注入是将不需要的命令注入SQL查询的行为。它与后面发生的事情没有任何关系,它是能够向数据库发送不需要的命令的行为。除了在前端显示数据外,这还会产生其他后果。通过一点探索和猜测,就有可能发现数据库的结构。然后,攻击者可能会导致数据库执行类似于以下内容的查询:

INSERT INTO admins (username, password) VALUES ('foo', 'bar')
等等,瞧,攻击者刚刚为自己创建了一个具有已知密码的根管理员帐户,将从前门进来

下面是一个很好的故事,可以引导您了解它:

您的特定数据库API是否允许此类查询通过是另一个问题;但是SQL注入肯定不仅仅是关于输出。

攻击者可以将id设置为:

…并且会得到卡尔的相关信息。他可以对所有用户名或ID重复这个过程,但仍然会得到很多他不应该得到的信息。这只会花更长的时间


因此,一般来说,不能说只查询一行就可以降低SQL注入的危险性。

大多数人不理解注入是什么

他们混淆了注入利用和注入本身

说到注入,只要在查询中允许不需要的代码,注入是可能的,即使注入的只是超出预期边界的Hello Kitty

所以,对于新手程序员能想出的数百万个问题的答案,如果我有这个,如果我没有这个,都是一样的-是的,注射是可能的

说到漏洞利用,有比你想象的更多的技术,其中一些相当复杂。那么,要回答这个问题,这种注入是可以利用的吗?答案很可能也是肯定的

所以,不要问自己这可能吗?。这个问题毫无意义。您只需要编写防注入代码。这就是为什么这个问题不好。因为你应该问

如何编写防注入代码? 相反。

仅仅是一个事实,SQL命令的意图可以通过 外部影响输入:

软件使用来自上游组件[…]的外部影响输入来构造SQL命令的全部或部分,[…]可以在发送到下游组件时修改预期的SQL命令

你的例子就是这样

请注意。你今天可能无法利用它,但也许其他人能够,无论是今天还是将来的某个时候

坦率地说,缺乏对SQL注入和SQL的了解是许多人无法识别SQL注入或SQL攻击漏洞的原因

对于这种缺乏知识的情况,您给出了一个完美的例子:…或1=1对于每一行都是真的,因此除非您的表为空,否则注入的UNION SELECT的结果集将永远不会显示在您的结果中


还请注意,除了UNION SELECT之外,还有其他利用技术。

作为对前面非常好的观点的一个次要跟进,以演示为什么返回的单个记录在任何方面都不安全。您可以使用GROUP_CONCAT aggregate函数

例如,id为:-

1 AND FALSE UNION SELECT 1, 'fred', GROUP_CONCAT(CONCAT_WS('-', id, username, password) ORDER BY id) FROM users -- 
这使用来自Hauke p.的代码来确保查询的第一部分不返回任何内容,然后在查询中使用UNION来获取所有用户ID、名称和密码。无需猜测现有id或名称


由于GROUP_CONCAT返回的字段的默认最大长度,这将略微下降,但当有人点击时,他们可能已经获得了30个用户的登录详细信息,他们可以很容易地添加WHERE id>xxx来获得下一批30条左右的数据。

这段代码对SQL注入非常开放。您是否尝试过SQL注入来截断表,而不是简单地尝试返回多条记录?为什么对这个问题进行向下投票?可以
一个巨大的互联网很好地支持它,并给它一个非常棒的答案。SQL注入不仅用于显示比select中预期的更多的结果。我可以注射3;跌落试验台并删除所有内容…不要用不同的条件来打扰自己,如果这个,如果那个。答案总是-是的。据我所知,MySQL不支持堆叠查询,这意味着您不能添加另一个insert语句,您只能通过添加union子句等来更改现有查询@user,这可能已经足够了。阅读这篇链接文章,它从多个角度说明了一个应用程序是如何以最意想不到的方式攻击攻击者的,即使该应用程序只允许一点点空间。很少情况下,它本身只是一个特定的SQL注入缺陷,通常SQL注入是攻击者在其他地方插入的第一个立足点。根据情况,您可以执行堆叠查询。例如,使用php有mysqli_multi_查询函数-我想我看到了您的逻辑,开始时的AND 1=0使语句的第一部分从不返回任何内容,因此只返回查询的UNION SELECT部分之后的值?是吗?没错。为了让它更清楚一点,我用FALSE替换了1=0。明白了!谢谢你,伙计!我很高兴在出丑之前问过你:
1 AND FALSE UNION SELECT id, username, password FROM users WHERE username="carl" LIMIT 1, 1 --
1 AND FALSE UNION SELECT 1, 'fred', GROUP_CONCAT(CONCAT_WS('-', id, username, password) ORDER BY id) FROM users --