Mysql 为什么这个SQL代码不安全?
我刚刚让一个朋友看了一些我用来从数据库中获取数据的代码,他告诉我这是非常不安全的,SQL注入是严重的垃圾 下面是我现在使用的代码:Mysql 为什么这个SQL代码不安全?,mysql,sql,sql-injection,Mysql,Sql,Sql Injection,我刚刚让一个朋友看了一些我用来从数据库中获取数据的代码,他告诉我这是非常不安全的,SQL注入是严重的垃圾 下面是我现在使用的代码: $id = $_GET['id']; $result = mysql_query("SELECT * FROM news WHERE id = $id") or die("err0r"); 他告诉我解决方案是将代码更改为: $id = intval($_GET['id']); $result = mysql_query("SELECT * FROM news WH
$id = $_GET['id'];
$result = mysql_query("SELECT * FROM news WHERE id = $id") or die("err0r");
他告诉我解决方案是将代码更改为:
$id = intval($_GET['id']);
$result = mysql_query("SELECT * FROM news WHERE id = $id") or die("err0r");
根据我的朋友,我的代码使任何用户都能够编辑我数据库中的内容:
http://mydomain.com/?p=news&id=38;DROP TABLE tablename;
有人能解释清楚他的意思吗
谢谢您,祝您度过愉快的一天如果您不尝试将id强制设置为整数,那么任何东西都可能在您的数据库上运行。例如,DROP TABLE命令。当然,有人仍然可以尝试在这里强制一个非常大的整数并导致溢出,我不知道这是否会导致一个相对较小的错误
请参见此处:查看经典插图
另一方面,如果您设置了一个测试服务器,那么您可以在导航到URL时看到代码的实际情况http://mydomain.com/?p=news&id=38;删除表tablename 如果您不尝试将id强制为整数,则任何内容都可能在您的数据库上运行。例如,DROP TABLE命令。当然,有人仍然可以尝试在这里强制一个非常大的整数并导致溢出,我不知道这是否会导致一个相对较小的错误
请参见此处:查看经典插图
另一方面,如果您设置了一个测试服务器,那么您可以在导航到URL时看到代码的实际情况http://mydomain.com/?p=news&id=38;删除表tablename 它确保$id是一个数字。它确保$id是一个数字。该URL将使$id='38;删除表tablename;' 第一个分号将结束当前查询,导致运行第二个分号,这将删除您的表 维基百科有一个很好的解释: 就像这样:=]
您还应该开始考虑当您需要的输入不是一个数字时,您将做些什么,这样intval就帮不上忙了。拥有一个对输入进行sanatize的功能总是很方便的——只是别忘了使用它,永远不要相信任何东西 该URL将使$id='38;删除表tablename;' 第一个分号将结束当前查询,导致运行第二个分号,这将删除您的表 维基百科有一个很好的解释: 就像这样:=]
您还应该开始考虑当您需要的输入不是一个数字时,您将做些什么,这样intval就帮不上忙了。拥有一个对输入进行sanatize的功能总是很方便的——只是别忘了使用它,永远不要相信任何东西 如果您不验证id并确保它是整数,则有人可以将id设置为1;投桌新闻;它将按原样发送到数据库,并可能删除新闻表。如果您进行验证以确保id是一个整数,则应该可以。另外,作为一种额外的预防措施,您可能希望确保脚本使用的数据库用户仅具有执行所需操作所需的确切权限级别—仅此而已。例如,如果您的程序无意删除表,请确保数据库用户没有此权限。如果您不验证id并确保它是整数,则有人可以将id设置为1;投桌新闻;它将按原样发送到数据库,并可能删除新闻表。如果您进行验证以确保id是一个整数,则应该可以。另外,作为一种额外的预防措施,您可能希望确保脚本使用的数据库用户仅具有执行所需操作所需的确切权限级别—仅此而已。例如,如果您的程序无意删除表,请确保数据库用户没有此权限。考虑如果有人发布http://www.mydomain.com?id=1; 投递表新闻 旧版本的PHP试图通过自动转义所有输入变量来自动防止这种情况;ie通过向输入中的任何引号字符添加斜杠,这样它们就不会破坏SQL查询。这不再是当前PHP版本中的默认设置,因为它会导致许多其他问题 然而,在您的例子中,您甚至没有在SQL查询中引用该变量,因此即使这种保护也不会对您有所帮助,因为黑客不需要包含任何引用来攻击您 intval解决方案在这种特定情况下确实会帮助您,但在其他情况下(例如,如果您需要处理字符串变量)则不会有帮助 正确的解决方案: 您应该对要传递到SQL查询中的所有变量使用mysql\u real\u escape\u string函数,以防止任何可能的黑客攻击,如:
$escaped_id = mysql_real_escape_string($id);
应将SQL字符串中的所有变量用引号括起来,如下所示:
$result = mysql_query("SELECT * FROM news WHERE id = '$escaped_id'");
顺便说一下。。。这是一个非常流行的链接来演示问题- 考虑一下如果有人发布http://www.mydomain.com?id=1; 升降台 ws 旧版本的PHP试图通过自动转义所有输入变量来自动防止这种情况;ie通过向输入中的任何引号字符添加斜杠,这样它们就不会破坏SQL查询。这不再是当前PHP版本中的默认设置,因为它会导致许多其他问题 然而,在您的例子中,您甚至没有在SQL查询中引用该变量,因此即使这种保护也不会对您有所帮助,因为黑客不需要包含任何引用来攻击您 intval解决方案在这种特定情况下确实会帮助您,但在其他情况下(例如,如果您需要处理字符串变量)则不会有帮助 正确的解决方案: 您应该对要传递到SQL查询中的所有变量使用mysql\u real\u escape\u string函数,以防止任何可能的黑客攻击,如:
$escaped_id = mysql_real_escape_string($id);
应将SQL字符串中的所有变量用引号括起来,如下所示:
$result = mysql_query("SELECT * FROM news WHERE id = '$escaped_id'");
顺便说一下。。。这是一个非常流行的链接来演示问题- 看看这里:看看这里:一点都不坏-但这并不意味着这不是一件重要的事情。一点都不坏-但这并不意味着这不是一件重要的事情。我要试试这个,看起来你知道你在说什么=谢谢老兄。mysql\u real\u escape\u string是一个好的开始,但它有问题,而且可能不应该被使用。更多信息:@Grim-确实如此,但真正的解决方案是使用不同的数据库库(如PDO)重写整个应用程序,这可能是一个很大的飞跃,不适合作为这个问题的建议。我要试试这个,看起来你知道你在说什么=谢谢man.mysql\u real\u escape\u string是一个好的开始,但它有问题,而且可能不应该被使用。更多信息:@Grim-确实如此,但真正的解决方案是使用不同的数据库库(如PDO)重写整个应用程序,这可能是一个很大的飞跃,不足以解决这个问题。