0

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

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

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

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

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

在视图中:

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

    }
}

问题

在为 object 赋值时,有什么方法可以水合或应用使用 htmlentites() 函数的自定义过滤器?

到目前为止的解决方案

  • 在分配给视图之前先水合到数组,但当我想要自定义方法时不是一个好主意。
  • 无论如何,在每个“回声”输出( echo $this->stripXSS($obj->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;
    }
4

1 回答 1

0

您可以在更改后刷新实体对象之前过滤学说实体的每个属性(或字符串属性),您可以使用 Doctrine 的 preFlush 挂钩,您只需编写 10 行代码,它将适用于所有实体。关注这篇文章-防止 XSS (ZendFramework & Doctrine 2)

于 2015-02-05T18:47:53.457 回答