今天早些时候,有人问了有关Web应用程序中输入验证策略的问题。
在撰写本文时,最高答案建议PHP
仅使用htmlspecialchars
和mysql_real_escape_string
。
我的问题是:这是否总是足够?还有更多我们应该知道的吗?这些功能在哪里分解?
对于数据库查询,请始终尝试使用准备好的参数化查询。在mysqli
和PDO
库支持这一点。这比使用转义功能(例如)更加安全mysql_real_escape_string
。
是的,mysql_real_escape_string
实际上只是一个字符串转义功能。这不是魔术子弹。它所要做的就是逃避危险字符,以便可以安全地在单个查询字符串中使用它们。但是,如果您不事先清理输入内容,那么您将容易受到某些攻击媒介的攻击。
想象以下SQL:
$result = "SELECT fields FROM table WHERE id = ".mysql_real_escape_string($_POST['id']);
您应该能够看到这很容易被利用。
假设id
参数包含公共攻击向量:
1 OR 1=1
那里没有危险的字符进行编码,因此它将直接通过转义过滤器。离开我们:
SELECT fields FROM table WHERE id= 1 OR 1=1
这是一个可爱的SQL注入向量,它将使攻击者可以返回所有行。要么
1 or is_admin=1 order by id limit 1
产生
SELECT fields FROM table WHERE id=1 or is_admin=1 order by id limit 1
在这个完全虚构的示例中,这使攻击者可以返回第一位管理员的详细信息。
这些功能虽然有用,但必须谨慎使用。您需要确保所有Web输入都经过一定程度的验证。在这种情况下,我们发现我们可以被利用,因为我们没有检查用作数字的变量实际上是数字。在PHP中,您应该广泛使用一组函数来检查输入是否为整数,浮点数,字母数字等。但是对于SQL,请注意准备好的语句的大部分值。如果上面的代码是预准备的语句,则它是安全的,因为数据库函数将知道这1 OR 1=1
不是有效的文字。
至于htmlspecialchars()
。那是它自己的雷区。
PHP中存在一个真正的问题,因为它具有与html相关的各种转义功能的全部选择,而对于确切的功能没有明确的指导。
首先,如果您位于HTML标记内,则确实会遇到麻烦。看着
echo '<img src= "' . htmlspecialchars($_GET['imagesrc']) . '" />';
我们已经在HTML标记中,因此我们不需要<或>做任何危险的事情。我们的攻击媒介可能就是javascript:alert(document.cookie)
现在结果HTML看起来像
<img src= "javascript:alert(document.cookie)" />
攻击直截了当。
情况变得更糟。为什么?因为htmlspecialchars
(以这种方式调用)仅编码双引号而不是单引号。所以如果我们有
echo "<img src= '" . htmlspecialchars($_GET['imagesrc']) . ". />";
我们的邪恶攻击者现在可以注入全新的参数
pic.png' onclick='location.href=xxx' onmouseover='...
给我们
<img src='pic.png' onclick='location.href=xxx' onmouseover='...' />
在这些情况下,没有魔术的子弹,您只需要自己修改输入即可。如果尝试滤除不良字符,您肯定会失败。采取白名单方法,只允许通过一些好的字符。查看XSS备忘单,了解有关如何实现多种向量的示例
即使htmlspecialchars($string)
在HTML标签之外使用,您仍然容易受到多字节字符集攻击向量的攻击。
您可能最有效的方法是使用mb_convert_encoding和htmlentities的组合,如下所示。
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
$str = htmlentities($str, ENT_QUOTES, 'UTF-8');
即使这样,由于IE6处理UTF的方式,它也容易受到攻击。但是,在IE6的使用率下降之前,您可能会使用较为有限的编码,例如ISO-8859-1。
问题内容: 在http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat- sheet/?akst_action=share- this上 ,有一节声称您可以使用某些亚洲字符编码绕过mysql_real_escape_string 用BIG5或GBK绕过mysql_real_escape_string() “注入线” に关する追加情
问题内容: 我正在与Hibernate合作保护我的网站免受SQL Injection。 我听说Hibernate Criteria API比HQL更强大。Hibernate Criteria Api是否可以完全防止SQL注入? 问题答案: 是的,它确实。 Criteria API以及HQL或JPQL中的查询参数均会转义参数,并且不会执行恶意SQL。 仅在您将参数简单地串联到查询中时,才会暴露此漏洞
问题内容: 我有点困惑,PHP中有很多函数,有些使用这个,有些使用那个。有些人使用:,,等 哪个是正确的,你们通常使用什么? 这是正确的吗(如果有的话,建议我做一个更好的): 该行可以防止MySQL注入和XSS攻击? 顺便说一句,除了XSS攻击和MySQL注入之外,还有其他需要注意的事情吗? 编辑 结论: 如果我想将字符串插入数据库,则无需使用,只需使用即可。在显示数据时,请使用,这是您的全部意思
问题内容: 我遇到了一群黑客。他们几次入侵了我客户的网站,我的客户更加生气:(我的客户丢失了他的数据库(有数百条记录),不得不输入所有:( 现在,我将进行更多介绍。 固定文件权限 更改了ftp和主机登录信息 清除所有远程mysql访问 现在正在处理SQL注入问题。我在管理面板登录参数中添加了mysql_real_escape_string。所以我还应该在哪里使用mysql_real_escape_
问题内容: 在PHP手册中,有一条注释: 注意:如果不使用此功能对数据进行转义,则该查询容易受到SQL注入攻击的攻击。 这足以进行反SQL注入吗?如果没有,您能举个例子和一个好的反SQL注入解决方案吗? 问题答案: 通常足以避免SQL注入。不过,这确实取决于它是否没有错误,即它 存在 脆弱性的可能性很小(但是这还没有在现实世界中体现出来)。准备好的语句是在概念上完全排除SQL注入的更好的替代方法。
问题内容: 可能重复: 绕过mysql_real_escape_string()的SQL注入 我还没有看到任何评价或没有过时的信息。因此,存在一个问题:mysql_real_escape_string()是否完全可以防止SQL注入?但是它已经非常过时了(它从‘09开始),所以从‘12的php 5.3和mysql 5.5开始,它是否可以完全保护? 问题答案: mysql_real_escape_st