Ric*_*ard 36 php sql sql-injection
我一直在阅读有关SQL注入攻击以及如何避免它们的内容,尽管我似乎永远无法在工作中制作"糟糕"的例子,例如看到这篇文章.
我在数据库中创建了一个PHP文件和一个表,有一个值传递$_GET并尝试通过执行删除表bob'); drop table students; --,但它不起作用.PHP自动转义\'并且查询有错误,没有造成任何伤害.尝试复制登录"攻击" AND WHERE 1=1等时出现同样的问题.
示例代码:
<?php
$id = $_GET['id'];
$sql = "INSERT INTO Users (Username) VALUES ($id)";
echo $sql;
mysql_query($sql) or die(mysql_error());
Run Code Online (Sandbox Code Playgroud)
而且我会通过 sql.php?id=1); delete from Users; --
那么这个过时的东西过去常常适用于PHP3或者什么东西,现在甚至新手都不受魔法引号之类的保护?
我在Ubuntu上使用PHP5.
Pek*_*ica 57
恰恰相反.魔术引号在PHP5中已被弃用,并将在PHP 5.4中完全删除,因为它们给编程世界带来了比他们做得更好的混乱.检查魔法引号是否有效,并在必要时严格逃避任何SQL输入仍然是非常非常重要的......虽然没有理由感觉不好,我们都已经在那里,并且我的不知不觉的屁股已被无数的魔法报价所拯救时间:)
关于魔术引号的PHP手册解释了一切.
Bil*_*win 20
历史上最大的身份盗窃是在2007年通过利用SQL注入漏洞实现的:参见" SQL注入攻击导致Heartland,Hannaford违规 "(ComputerWorld,8/18/2009).
OWASP 在2007年报告说,注入攻击(其中SQL注入就是一个例子)仍然是最常见的软件安全问题之一.
您还可以搜索最近的SQL注入新闻,并查找每月报告的许多案例.
但是,XKCD漫画中的示例不一定是最常见的漏洞利用类型.通过在一个请求中执行第二个SQL语句来删除表可能不会使攻击者获得有价值的数据,这只会是故意破坏.
此外,一些查询接口无论如何都不允许默认多查询.也就是说,无论分号如何,数据库客户端API都只执行给定SQL字符串的单个语句.这打败了卡通中所示的例子.
注意:默认情况下,query()已知PDO的方法支持多查询.因此,它是易受XKCD式的攻击.
正如其他人所指出的那样,更可能的风险是SQL注入会改变SQL表达式的逻辑,并将查询应用于除预期之外的额外行.
例如:
$sql = "UPDATE Users SET PASSWORD = MD5('" . $_POST["password"] . "'||salt) " .
"WHERE user_id = " . $_POST["userid"];
Run Code Online (Sandbox Code Playgroud)
当我将带参数userid设置的请求发送到字符串时会发生什么123 OR userid=456?我会重置我自己的密码(用户ID 123)以及用户ID 456的密码.即使用每用户盐哈希密码也无法防止这种情况发生.现在我可以登录任一帐户.
有很多方法可以执行SQL注入.
Pau*_*xon 10
这种特殊的攻击不起作用,因为mysql_query只会执行一个语句.
我仍然可以滥用您的代码,例如,如果我安排了id,那么SELECT password FROM Users WHERE Username='admin'我可能有机会让您的系统暴露一些内部信息.
基本上,如果您允许未经过滤的输入到您的SQL中,将会有一些非常有创意的方法来创建您不期望的数据,并暴露您不想要的数据!
哦,我的.. SQL注入不是一个风险,它是一个巨大的安全漏洞.它主要存在于php中,因为API使您希望将任何旧数据插入到SQL查询中.
当我看到用PHP或ASP编写的网站时,我可以闻到他们喜欢的SQL注入向量.人们试图用保护他们的PHP应用程序mysql_real_escape_string(),并intval()与其他语言的做人之道.这是个错误.这就像用C编写而不是Java或Python编码,在前者中,你犯了一个错误而你已经死了,但在后者中,只存在语义缺陷.
我强烈建议人们使用mysqli和预先准备好的语句,或者其他任何参数化的文件,将文本代入代码然后解释它只是首先恕我直言的坏习惯.
另一方面,PHP的神奇报价是愚蠢的,谢天谢地,不赞成使用.它只会造成弊大于利.如果您依赖魔术引号,则表示您的应用将在禁用魔术引号时拥有.同样,它可能会破坏其他不期望输入中的转义字符串的应用程序.
这仍然是一个大问题.您不能假设在您可能使用的每个PHP安装中都启用了magic_quotes.
要查看魔法引号是否已打开并清除魔法引号中的乱七八糟:
if ( get_magic_quotes_gpc() !== 0 ) { $foo = stripslashes( $foo ); }
Run Code Online (Sandbox Code Playgroud)
然后稍微清理你的陈述:
$foo = mysql_real_escape_string( $foo );
$sql = "select * from foo where bar='{$foo}'";
Run Code Online (Sandbox Code Playgroud)
等等
事实上,magic_quotes如果你有能力这样做,你最好只是严格转向.
我希望能帮助你.
bobby表示例不适用于mysql接口,因为它不会在一次调用中执行多个查询.mysqli界面容易受到多次查询攻击.mysql接口更容易受到特权提升攻击:
在您的表单中我输入帐号:admin密码:' or 1=1 --这样您的典型登录sql : select * from users where user_name = '$admin' and password = '$password'. 或者导致这是真的,让你登录.
正如我之前在stackoverflow上多次提到的,我是PDO的坚定支持者,只是停止使用老式的mysql,自己和你的客户一个大忙,学习PDO(这很容易)并利用准备好的语句和绑定参数.即使您不需要准备好的语句表现,您仍然可以获得安全性好处.
另外,如果魔术引号设置为on,我会建议在客户端面对整个应用程序崩溃.这只是为了保护愚蠢和惹恼智能的资源.(它使用更多的CPU而不是手动转义,因为它会对所有内容进行编码,即使您不需要它也是如此)