Doctrine 2,自定义条带xss过滤器?

时间:2012-08-02 15:38:53

标签: php doctrine-orm

所以我一直在努力实现一个通用的解决方案,用于在进入视图之前剥离XSS注入。

这很好用(对于数组,简单对象和字符串)

$this->view->assign('data', '<script>alert("test")</script>');
$this->view->assign('data', array(0 => '..xss attack ...'));

但是,doctrine有延迟加载,这意味着在视图中你不会过滤延迟加载器获取的Doctrine记录。在这样:

$this->view->assign('result', $this->model->getAllUsers());

在视图中:

// Here comes the problem.
foreach($result as $user){
    foreach($user->getComments() as $comment){

    }
}

问题

在为对象赋值时,有没有办法补充或应用自定义过滤器使用htmlentites()函数?

到目前为止的解决方案

  • 在分配到视图之前水合到数组,但是当我想要自定义方法时,这不是一个好主意。
  • 在每个“echo”输出上使用转义功能(echo $ this-&gt; stripXSS($ obj-&gt; getName())无论如何,这不安全,你可能会忘记这一点并不是一个好主意通用解决方案。

这是我为剥离XSS注入而创建的函数。 (适用于assign())

/**
     * Recursive method.
     *
     * Can remove XSS attacks from both strings and arrays.
     * Uses htmlentities, ENT_QUOTES , UTF-8
     * 
     * @param mixed $var A variable to strip for XSS attacks.
     */
    public function stripXSS($var){
        // Well this was easy, lets escape that shall we ?
        if (is_string($var))return htmlentities($var, ENT_QUOTES, 'UTF-8');

        // This is a array, here we can need recursive...
        if (is_array($var)){
            foreach($var as $k => $v){
                // $v can be array too, and any type for that case ... so .. make it call itself.
                $var[$k] = $this->stripXSS($v);
            }
            // Return the array.
            return $var;
        // Exceptions assigned is not clonable, skip it.
        }else if (is_object($var) && !($var instanceof \Exception) && !($var instanceof \Closure)){
            // Use reflection to set properties.


            if (!method_exists($var, '__clone')){
                // Clone it, we don't want anything to change except in the VIEW...
                $var = clone $var;

                // Get its properties..
                $ref = new \ReflectionObject($var);
                $props = $ref->getProperties();
                foreach($props as $prop){
                    $prop->setAccessible(true);
                    $val = $prop->getValue($var);
                    if (is_string($val) || is_array($val) || is_object($val)){
                        $prop->setValue($var, $this->stripXSS($val));
                    }
                }
            }

        }

        // Well, this is either a int, float and so fourth - meaning it does not need to be escaped. Return.
        return $var;
    }

1 个答案:

答案 0 :(得分:0)

你可以在更改后刷新实体对象之前过滤doctrine实体的每个属性(或字符串属性),你可以使用Doctrine的preFlush钩子,你只需编写10行代码,它将适用于所有实体。请关注此帖子 - Prevent XSS (ZendFramework & Doctrine 2)