PHP 5.5短标签(short_open_tag)=on会存在安全漏洞?

13

我已经升级到 PHP5.5,PHP.ini 中现在 short_open_tag=off,我之所以知道这一点是因为一些文件现在不能正常运行,因为使用了 <? 而不是 <?php

现在有两种解决方案:查找任何 PHP 文件并将开放标签更改为 <?php 或激活 short_open_tag=on

第二个选项是否存在安全问题?


可能是Are PHP short tags acceptable to use?的重复问题。 - raina77ow
1个回答

25
不是直接的安全漏洞,但在适当条件下可能会成为一个安全漏洞。
首先,让我们来看规格标准。在PHP 5.4及更高版本中,short_open_tag=on指令适用于除了echo标签<?=之外的所有短标签。 通常认为,在代码中大量使用短标签是一种不好的实践,因为它会影响可移植性。我个人不使用短标签。 自从PHP 5.4和>= 5.4版本以来,短echo标签<?=始终可用,并且不受short_open_tag ini指令的影响。我认为这个将echo标签与其他标签分开的决定是正确的。
实际上,PSR标准建议这样做。所以: PSR-1 建议只使用 <?php ?><?= ?>(echo 短标签) - 没有其他变体,而 PSR-2 建议在仅 PHP 文件中不要关闭标签。这可能看起来很奇怪,但有时你的代码中可能会因为单个空格 (' ') 字符出现在您的打开或关闭括号之前或之后而导致无法跟踪的错误。这是一个众所周知的问题。我遵循这两种做法,因为我曾经因旧项目中使用不同标签而遇到过很多问题。

所有这一切都始于何时?

在PHP早期,人们开始意识到PHP标签与XML和ASP的标签冲突。是的,你可以使用<% //code here %>作为开/关标签。 然后决定使用<?php ?>来区分PHP自身和XML和ASP,这是一种PHP代码的顶级命名空间。 实际上,ASP标签被引入是为了方便ASP开发人员采用PHP。
ASP标记由asp_tags ini指令处理,它们应该关闭。
再次强调-进行短标记的辩论,这就是为什么现在有一个短标记和短echo标记之间的区别。我认为这是一件好事。只需替换您的遗留代码中的所有短标记即可。
现在谈谈安全问题。
唯一需要担心的情况是当您有一些用户输入以某种方式通过PHP解释器时。您将需要剥离:
  • 普通PHP标签
  • 短PHP标签
  • 短回声标签
  • ASP样式标签
  • 字节移位代码注入
  • 任何包含<script language="php"></script>的内容

最后这部分 - <script language="php"></script> - 非常重要,因为它现在并没有被使用(我们最好不要用它),但据我所知,PHP解释器仍然支持它。因此,在这个HTML脚本标记之间的任何内容都将被解释为PHP。所有这些在这里都有很好的解释

什么是字节移位代码注入

这有点难以解释,但基本思想是它是混淆的代码注入。因此,如果攻击者某种方式能够注入一些PHP代码,并且他/她不希望维护者/开发人员立即识别它,他可以做如下操作:

$smth = 'rpub "lbh ner nggnpxrq naq lbhe jrofvgr unf orra gnxra bire";';
eval(str_rot13($smth));

这个想法是“一堆字符串”是一个php代码字符串,但是进行了字节移位以使其混淆。在我的例子中,eval()将接收echo "you are attacked and your website has been taken over"。我使用str_rot13(),因为很容易将字符串混淆回来和向前混淆,但这可以是基于chr()ord()或任何其他字符串操作函数的自定义函数。
防止这种攻击的最佳方法是防止eval()执行。您应该能够通过disable_functions ini指令来实现这一点。当然,解析您的代码!但也要禁用eval()
这种攻击在像WordPress这样的系统中很难被察觉,因为它们在数据库中存储了许多不必要的东西。我亲眼见过这种代码注入被用于网站(不是我维护的:D),有两种方式:

  • 数据库损坏(当应用程序存储需要解释的内容时可能发生)
  • 直接PHP源文件损坏 - 这更容易分析 - 只需使用 diff 将其与存储库中的最新版本进行比较或将其与某个源备份进行比较(同样通过 diff)。

希望这可以帮助您。 因此,请开始遵守PSR标准

  • 除echo标签<?=外,不要使用短标记
  • 禁用ASP风格标记
  • 注意代码注入。

2
"<script language="php"></script>" 是什么?我竟然在编写 PHP 代码超过十年后才知道这种语法?我需要检查一下是否存在未知的安全漏洞...唉。 - Abhi Beckert
是的,不幸的是这个旧功能应该还在。我实际上需要为5.5验证这一点。我会检查一下,但我不记得它被删除了。 - Borislav Sabev
+1 对于完美的详细解释,只有最后一个单词的小错别字让人烦恼 :) - CodeBird
非常好的回答。对于保持警惕非常有帮助。 - Ranjith Siji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接