所以我一直在尝试实现一个通用的解决方案,在进入视图之前剥离 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;
}