php str_replace的替换漏洞

定义和用法

  str_replace() 函数使用一个字符串替换字符串中的另一些字符。

  语法

  str_replace(find,replace,string,count)

  参数 描述

  find 必需。规定要查找的值。

  replace 必需。规定替换 find 中的值的值。

  string 必需。规定被搜索的字符串。

  count 可选。一个变量,对替换数进行计数。

  提示和注释

  注释:该函数对大小写敏感。请使用 str_ireplace() 执行对大小写不敏感的搜索。

  注释:该函数是二进制安全的。

  例子 1

  

复制代码 代码如下:

  <?php

  echo str_replace("world","John","Hello world!");

  ?>

  输出:

  Hello John!

  例子 2

  在本例中,我们将演示带有数组和 count 变量的 str_replace() 函数:

  

复制代码 代码如下:

  <?php

  $arr = array("blue","red","green","yellow");

  print_r(str_replace("red","pink",$arr,$i));

  echo "Replacements: $i";

  ?>

  输出:

  Array

  (

  [0] => blue

  [1] => pink

  [2] => green

  [3] => yellow

  )

  Replacements: 1

  例子 3

  

复制代码 代码如下:

  <?php

  $find = array("Hello","world");

  $replace = array("B");

  $arr = array("Hello","world","!");

  print_r(str_replace($find,$replace,$arr));

  ?>

  输出:

  Array

  (

  [0] => B

  [1] =>

  [2] => !

  )

  漏洞相关函数:

  <?php

  $arr1 = Array(

  'http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020',

  'http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020-1',

  'http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020-2'

  );

  $arr2 = Array(

  'http://localhost/root/ups/af48056fc4.jpg',

  'http://localhost/root/ups/cf33240aa3.jpg',

  'http://localhost/root/ups/c30e40419b.jpg'

  );

  $data = '

  <img src="http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020"/>

  <img src="http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020-1"/>

  <img src="http://dl.glzy8.com/img/img/offer/29/24/70/20/29247020-2"/>';

  $data = str_replace($arr1,$arr2,$data);

  var_dump($data);

  ?>

  替换后的结果是:

  string(169) "<img src="http://localhost/root/ups/af48056fc4.jpg"/><img src="http://localhost/root/ups/af48056fc4.jpg-1"/><img src="http://localhost/root/ups/af48056fc4.jpg-2"/>"str_replace 函数的声明大概是这样: str_replace($search, $replace, $input[,&$count]), 比如在对一个字符串进行替换操作, $input 就是源字符串(称为数据源). 这很不合理,因为它把数据源放在第3位, 而 str_pos, strtok, str_repeat 等等函数都是把数据源放在第1位.也就是说str_replace并没有替换掉数组中相对应的字符串,而是把数组中的第一个替换,然后把相同的字符串后多余的合并。

  解决办法:

  function strrplace($arr1,$arr2,$data){

  if(is_array($arr1)) {

  foreach($arr1 as $key => $value)  {

  $data = str_replace_once($value, $arr2[$key], $data);

  } }

  return $data;

  }

  function str_replace_once($needle, $replace, $data) //替换第一次

  {

  $pos = strpos($data, $needle);

  if ($pos === false) {

  return $data;

  }

  return substr_replace($data, $replace, $pos, strlen($needle));

  }