そのため、ビューに移動する前に 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){
}
}
質問
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;
}