preg_replace() 函数与/e漏洞
preg_replace 函数,执行一个正则表达式的搜索和替换。
语法
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换。
参数说明:
- 
$pattern: 要搜索的模式,可以是字符串或一个字符串数组。 
- 
$replacement: 用于替换的字符串或字符串数组。 
- 
$subject: 要搜索替换的目标字符串或字符串数组。 
- 
$limit: 可选,对于每个模式用于每个 subject 字符串的最大可替换次数。 默认是-1(无限制)。 
- 
$count: 可选,为替换执行的次数。 
返回值
如果 subject 是一个数组, preg_replace() 返回一个数组, 其他情况下返回一个字符串。
如果匹配被查找到,替换后的 subject 被返回,其他情况下 返回没有改变的 subject。如果发生错误,返回 NULL。
实例
将google替换为runoob:
<?php $string = 'google 123, 456'; $pattern = '/(\w+) (\d+), (\d+)/i'; $replacement = 'runoob ${2},$3'; echo preg_replace($pattern, $replacement, $string); ?>
执行结果如下所示:
runoob 123,456
删除空格字符:
<?php $str = 'runo o b'; $str = preg_replace('/\s+/', '', $str); // 将会改变为'runoob' echo $str; ?>
执行结果如下所示:
runoob
使用基于数组索引的搜索替换:
<?php $string = 'The quick brown fox jumped over the lazy dog.'; $patterns = array(); $patterns[0] = '/quick/'; $patterns[1] = '/brown/'; $patterns[2] = '/fox/'; $replacements = array(); $replacements[2] = 'bear'; $replacements[1] = 'black'; $replacements[0] = 'slow'; echo preg_replace($patterns, $replacements, $string); ?>
执行结果如下所示:
The bear black slow jumped over the lazy dog.
按理说顺序应该是:The slow black bear jumped over the lazy dog. 但结果明显不对。
问题出在 $patterns 和 $replacements 的索引顺序上。虽然 $replacements 的索引顺序是 [2]、[1]、[0],但 PHP 在处理数组时会自动对索引进行排序,因此 $patterns 和 $replacements 的实际顺序是按照索引从小到大排列的。
/e漏洞
这个函数有个 “/e” 漏洞,“/e” 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码进行执行。如果这么做要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。
preg_replace("/abc/e", system('ls'), "abcabc")
这个时候“/abc"可以匹配"abcabc"两次,就会执行两次system('ls')
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号