Xss-фильтр для фреймворка Yii версия 0.0.2
Совсем недавно я писал про свой XSS фильтр для фреймворка Yii. Сегодня хочу рассказать о его новой версии и о том, что собсвенно говоря изменилось. И так…
— код для фильтрации данных, взят из последней (2.3.4) версии фреймворка Kohana;
— появилась возможность указывать какие экшены необходимо обрабатывать фильтром;
Пример:
В качестве параметра 'actions' могут быть:
— '*' или 'all' — фильтруются все экшены (по умолчанию);
— можно указать экшены через запятую;
Пример:
'actions' => 'admin,manage' — фильтровать только экшены admin и manage
— появилась возможность обрабатывать HTML-тэги;
Пример конфигурации фильтра для обработки тэгов:
В качестве параметра 'tags' могут быть:
— 'strict' — ко всем параметрам применяется функция strip_tags (используется по умолчанию);
— 'soft' — ко всем параметрам применяется функция htmlspecialchars;
— 'none' — не фильтровать данные;
Приведу весь код фильтра:
Скачать XSS-фильтр из репозитория расширений Yii
Скачать XSS-фильтр c google code
Буду рад критике и замечаниям!
— код для фильтрации данных, взят из последней (2.3.4) версии фреймворка Kohana;
— появилась возможность указывать какие экшены необходимо обрабатывать фильтром;
Пример:
public function filters()
{
return array(
array(
'application.filters.YXssFilter',
'clean' => 'all',
'actions' => 'all'
)
);
}
В качестве параметра 'actions' могут быть:
— '*' или 'all' — фильтруются все экшены (по умолчанию);
— можно указать экшены через запятую;
Пример:
'actions' => 'admin,manage' — фильтровать только экшены admin и manage
— появилась возможность обрабатывать HTML-тэги;
Пример конфигурации фильтра для обработки тэгов:
public function filters()
{
return array(
array(
'application.filters.YXssFilter',
'clean' => 'all',
'tags' => 'strict'
)
);
}
В качестве параметра 'tags' могут быть:
— 'strict' — ко всем параметрам применяется функция strip_tags (используется по умолчанию);
— 'soft' — ко всем параметрам применяется функция htmlspecialchars;
— 'none' — не фильтровать данные;
Приведу весь код фильтра:
<?php
/**
* @author Opeykin A. <http://andrey.opeykin.ru> <developer@allframeworks.ru>
* @version 0.0.2
* @package filters
*
* Фильтр предназначен для фильтрации входных данных, c целью предотвратить xss атаки.
* Для фильтрации используются регулярные выражения из фреймворка Kohana версии 2.3.4
*
* @example
*
* public function filters()
* {
* return array(
* array(
* 'application.filters.XssFilter',
* 'clean' => '*',
* 'tags' => 'strict',
* 'actions' => 'all'
* )
* );
*
* }
*
* Описание параметров
*
* В качетве параметра 'clean' могут быть:
* - 'all' - фильтруются GET,POST,COOKIE,FILES массивы;
* - '*' - аналог ALL;
* - так же возможно сочетание любых из параметров, например GET,COOKIE или POST,FILES
* В качестве параметра 'tags' могут быть:
* - 'strict' - ко всем параметрам применяется функция strip_tags (используется по умолчанию)
* - 'soft' - ко всем параметрам применяется функция htmlspecialchars
* - 'none' - не фильтровать
* В качестве параметра 'actions' могут быть:
* - '*' или 'all' - фильтруются все экшены
* - можно указать экшены через запятую, пример
* 'actions' => 'admin,manage' - фильтровать только экшены admin и manage
*/
class YXssFilter extends CFilter
{
public $clean = '*';
public $tags = 'strict';
public $actions = '*,all';
protected function preFilter($filterChain)
{
$this->actions = trim(strtoupper($this->actions));
// если экшн обрабатывать нет необходимости - просто выходим из фильтра
if($this->actions != '*' && $this->actions != 'ALL' && !in_array($filterChain->action->id,explode(',',$this->actions)))
{
return true;
}
$this->clean = trim(strtoupper($this->clean));
$this->tags = trim(strtoupper($this->tags));
$data = array(
'GET' => &$_GET,
'POST' => &$_POST,
'COOKIE' => &$_COOKIE,
'FILES' => &$_FILES
);
if($this->clean === 'ALL' || $this->clean === '*')
{
$this->clean = 'GET,POST,COOKIE,FILES';
}
// по умолчанию - strict
if(!in_array($this->tags,array('STRICT','SOFT','NONE')))
{
$this->tags = 'STRICT';
}
$dataForClean = split(',',$this->clean);
if(count($dataForClean))
{
foreach ($dataForClean as $key => $value)
{
if(isset ($data[$value]) && count($data[$value]))
{
$this->doXssClean($data[$value]);
}
}
}
return true;
}
private function doXssClean(&$data)
{
if(is_array($data) && count($data))
{
foreach($data as $k => $v)
{
$data[$k] = $this->doXssClean($v);
}
return $data;
}
if(trim($data) === '')
{
return $data;
}
// перед фильтрацией разберемся с тегами
switch ($this->tags)
{
case 'STRICT':
$data = strip_tags($data);
break;
case 'SOFT':
$data = htmlentities($data,ENT_QUOTES,'UTF-8');
break;
case 'NONE':
break;
// по умолчанию - strict
default:
$data = strip_tags($data);
}
// xss_clean function from Kohana framework 2.3.4
$data = str_replace(array('&','<','>'), array('&','<','>'), $data);
$data = preg_replace('/(*\w+)[\x00-\x20]+;/u', '$1;', $data);
$data = preg_replace('/(*[0-9A-F]+);*/iu', '$1;', $data);
$data = html_entity_decode($data, ENT_COMPAT, 'UTF-8');
// Remove any attribute starting with "on" or xmlns
$data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data);
// Remove javascript: and vbscript: protocols
$data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data);
$data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data);
// Only works in IE: <span style="width: expression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data);
$data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data);
// Remove namespaced elements (we do not need them)
$data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data);
do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
return $data;
}
}
?>
Скачать XSS-фильтр из репозитория расширений Yii
Скачать XSS-фильтр c google code
Буду рад критике и замечаниям!
Юпи! — CMS на Yii – http://yupe.ru
Исходный код – https://github.com/yupe/yupe
Присоединяйтесь!
-
xoma,
- 21 июля 2009, 16:23
- рейтинг: +1

- SZares
- 07 августа 2009, 10:34
Yii понравился после первого беглого обзора, и в первую очередь — хорошо продуманной архитектурой и завершенностью, в отличии от некоторых других оболочек, где многое приходилось делать «на коленях с напильником в руках»…
Это хорошая идея — интегрировать мощный Xss-фильтр в YII!
Жаль — пока что мало энтузиастов в этой области, возможно, в силу своей тривиальной занятости, менталитета…
Это хорошая идея — интегрировать мощный Xss-фильтр в YII!
Жаль — пока что мало энтузиастов в этой области, возможно, в силу своей тривиальной занятости, менталитета…

- xoma
- 27 января 2010, 13:34
Интересно зачем я сделал параметр actions… Ведь управлять действиями можно и стандартными свойствами Yii.
Комментарии (6) свернуть | развернуть