有人可以解释/ e正则表达式修饰符吗?

Yam*_*ami 16 php regex

我目前正在提高我对HTML,PHP,JavaScript等安全漏洞的了解.几个小时前,我/e在正则表达式中偶然发现了修饰符,但我仍然无法理解它是如何工作的.我已经看了一下文档,但这并没有真正帮助.

我理解的是,可以操纵此修饰符以使某人有机会执行PHP代码(例如,preg_replace()).我已经看到以下示例描述了一个安全漏洞,但没有解释,所以有人可以解释一下如何调用phpinfo()以下代码吗?

$input = htmlentities("");
if (strpos($input, 'bla'))
{
   echo preg_replace("/" .$input ."/", $input ."<img src='".$input.".png'>", "bla");
}
Run Code Online (Sandbox Code Playgroud)

Gli*_*ire 46

ePHP中的Regex修饰符,包含示例漏洞和替代方案

什么e,举个例子......

e改性剂是一种过时的regex修改它允许您将正则表达式中使用PHP代码.这意味着您解析的任何内容都将被评估为您的程序的一部分.

例如,我们可以使用这样的东西:

$input = "Bet you want a BMW.";
echo preg_replace("/([a-z]*)/e", "strtoupper('\\1')", $input);
Run Code Online (Sandbox Code Playgroud)

这将输出 BET YOU WANT A BMW.

如果没有e修饰符,我们会得到非常不同的输出:

strtoupper('')Bstrtoupper('et')strtoupper('') strtoupper('you')strtoupper('') strtoupper('want')strtoupper('') strtoupper('a')strtoupper('') strtoupper('')Bstrtoupper('')Mstrtoupper('')Wstrtoupper('').strtoupper('')
Run Code Online (Sandbox Code Playgroud)

e......的潜在安全问题

e修饰符过时出于安全原因.以下是您可以轻松遇到的问题示例e:

$password = 'secret';
...
$input = $_GET['input'];
echo preg_replace('|^(.*)$|e', '"\1"', $input);
Run Code Online (Sandbox Code Playgroud)

如果我将输入提交为"$password",则此函数的输出将为secret(演示).因此,我很容易访问会话变量,后端使用的所有变量甚至eval('cat /etc/passwd');通过这个编写得很糟糕的代码对应用程序(?)进行更深层次的控制.

与类似的已弃用的mysql库一样,这并不意味着您不能编写不受漏洞影响的代码e,只是因为它更难以编写.

你应该用什么......

您应该在几乎所有考虑使用修饰符的地方使用preg_replace_callbacke.在这种情况下,代码绝对不是那么简短,但不要让那个愚弄你 - 它的速度是原来的两倍:

$input = "Bet you want a BMW.";
echo preg_replace_callback(
    "/([a-z]*)/",
    function($matches){
        foreach($matches as $match){
            return strtoupper($match);
        }
    }, 
    $input
);
Run Code Online (Sandbox Code Playgroud)

在性能上,没有理由使用e......

mysql库(出于安全目的而弃用)不同,e对于大多数操作而言,它并不比其替代方法快.对于给出的示例,它的速度是缓慢的两倍:preg_replace_callback(对于50,000次操作为0.14秒)对比e修饰符(对于50,000次操作为0.32秒)

  • 固定,不知道为什么我去了切线. (2认同)
  • +1,提供一个很好的明确例子.这也说明了为什么它对性能如此糟糕 - 在一行代码中调用了14个eval()`.哎哟.`eval()`已经足够慢了. (2认同)
  • @Spudley:[preg_replace_callback](https://eval.in/33014)(50,000 次操作0.14 秒)与[e 修饰符](https://eval.in/33015)(50,000 次操作0.32 秒)的性能比较 (2认同)

Spu*_*ley 5

e改性剂是特定PHP-改性剂触发器PHP运行所得到的字符串作为PHP代码。它基本上是eval()包裹在正则表达式引擎中。

eval()本身被认为是安全风险和性能问题;将其包装在正则表达式中会显着放大这两个问题。

因此,它被认为是不好的做法,并且从即将发布的 PHP v5.5 开始正式弃用。

PHP 现在为多个版本提供了一种替代解决方案 形式preg_replace_callback(),它使用回调函数而不是使用eval(). 这是做这种事情的推荐方法。

具体到您引用的代码:

e在问题中给出的示例代码中没有看到修饰符。它在每一端都有一个斜线作为正则表达式分隔符;将e不得不在外面的是,它不是。因此,我认为您引用的代码不会直接容易受到将e修饰符注入其中的影响。

但是,如果$input包含任何/字符,它很容易被完全破坏(即由于无效的正则表达式而引发错误)。如果它有其他任何使其成为无效正则表达式的内容,则同样适用。

因此,使用未经验证的用户输入字符串作为正则表达式模式的一部分是一个坏主意 - 即使您确定它不会被黑客入侵以使用e修饰符,也可以通过以下方式实现许多其他恶作剧它。