为了账号安全,请及时绑定邮箱和手机立即绑定

htmlSpecialchars和MySQL_REARY_EXECH_String是否保证PHP代码

/ 猿问

htmlSpecialchars和MySQL_REARY_EXECH_String是否保证PHP代码

慕尼黑的夜晚无繁华 2019-06-20 16:27:20

htmlSpecialchars和MySQL_REARY_EXECH_String是否保证PHP代码不受注入的影响?

今天早些时候有人问了一个关于Web应用中的输入验证策略.

在撰写本报告时,最上面的答案是PHP只是使用htmlspecialcharsmysql_real_escape_string.

我的问题是:这是否总是足够的?我们还需要知道更多吗?这些功能在哪里分解?


查看完整描述

3 回答

?
撒科打诨

除了Cheekysoft的出色回答:

  • 是的,它们会保护你的安全,但前提是它们的使用是绝对正确的。如果不正确地使用它们,您将仍然容易受到攻击,并且可能会出现其他问题(例如,数据损坏)。
  • 请改用参数化查询(如上文所述)。您可以通过例如PDO或PEARDB之类的包装器使用它们。
  • 确保魔术_引号_gpc和魔术_引号_运行时在任何时候都是关闭的,并且不会意外地打开,甚至不会被短暂地打开。这些都是PHP开发人员为防止安全问题(破坏数据)而进行的一次早期和严重错误的尝试。

在防止HTML注入(例如跨站点脚本)方面并没有真正的灵丹妙药,但如果您使用库或模板系统输出HTML,则可以更容易地实现它。阅读相关文档,以了解如何恰当地逃避事物。

在HTML中,需要根据上下文进行不同的转义。对于放入Javascript中的字符串尤其如此。


查看完整回答
反对 回复 2019-06-20
?
收到一只叮咚

我绝对同意上述的说法,但我想补充一件事,以回应Cheekysoft的答覆,特别是:

当涉及到数据库查询时,始终尝试并使用准备好的参数化查询。mysqli和PDO库支持这一点。这比使用转义函数(如MySQL_REAL_EXECH_String)安全得多。

是的,MySQL_REARY_EXIFE_String实际上只是一个字符串转义函数。这不是一颗神奇的子弹。它所要做的就是转义危险字符,以便它们可以安全地在单个查询字符串中使用。但是,如果您不事先清理您的输入,那么您将容易受到某些攻击向量的攻击。

想象一下下面的SQL:

$Response=“从表中选择字段id=”.mysql_Real_EXECH_String($_POST[‘id’]);

您应该能够看到这很容易被利用。假设id参数包含公共攻击向量:

1或1=1

没有危险的字符在那里编码,所以它将直接通过转义过滤器。离开我们:

从表中选择字段,其中id=1或1=1

我编写了一个快速的小函数,放在我的数据库类中,它将剔除任何不是数字的东西。它使用PREG_REPLE,所以有一个更优化的函数,但它在紧要关头工作.

function Numbers($input) {
  $input = preg_replace("/[^0-9]/","", $input);
  if($input == '') $input = 0;
  return $input;}

所以不要用

$Resue=“从表中选择字段,其中id=”.mysqlrealfreestring(“1 or 1=1”);

我会用

$READ=“从表中选择字段,其中id=”.Numbers(“1 or 1=1”);

它将安全地运行查询。

从表中选择字段,其中id=111

当然,这只是阻止了它显示正确的行,但我认为这对试图将SQL注入到您的站点的人来说不是什么大问题;)


查看完整回答
反对 回复 2019-06-20
?
HUH函数

当涉及到数据库查询时,始终尝试并使用准备好的参数化查询。这个mysqliPDO图书馆支持这一点。这比使用转义函数(如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='...' />

在这种情况下,没有灵丹妙药,你只需要自己对输入进行santise。如果你试着过滤掉坏角色,你肯定会失败的。采取白名单的方法,只让通过的字符是好的。看XSS备忘单关于向量的多样性的例子

即使你用htmlspecialchars($string)在HTML标记之外,您仍然容易受到多字节字符集攻击向量的攻击.

您可以使用的最有效的方法是将mb_COMPATE_CONITY和html实体组合在一起,如下所示。

$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');$str = htmlentities($str, ENT_QUOTES, 'UTF-8');

即使这样,IE6也很脆弱,因为它处理UTF的方式。但是,在IE6的使用率下降之前,您可能会退回到更有限的编码,比如ISO-8859-1。

有关多字节问题的更深入研究,请参见https://stackoverflow.com/a/12118602/1820


查看完整回答
反对 回复 2019-06-20

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信