Фильтрация POST&GET или xss защита
#1
Posted 12 March 2009 - 01:28 AM
qiang советует напрямую заюзать filter_input, товарищ jimezam предложил связку Yii с Kohana, чтобы пользоваться функциями Kohan'ы...
Последний вариант кажется удобным, но как-то не хочется в проект еще и кохану втыкать...
Может у кого есть идеи на этот счет? Или готовые варианты?
#2
Posted 12 March 2009 - 06:59 AM
Начинку (регулярки, которые все и фильтруют - взял их Kohana 2.3.1)...
Думаю за выходные допишу (к сожалению раньше не получится)...
#3
Posted 12 March 2009 - 11:06 AM

А поподробнее про данный варинат защиты где почитать, а то по ходу у мен в образовании пробел... Ну что такое XSS я знаю, а вот как защищаться - не.
#4
Posted 12 March 2009 - 02:03 PM
1) Вычищать данные при сохранении (например инсерт в базу)
2) Вычищать данные при отображение (при выводе на страницу)
Лично я предпочитаю первый способ - для чего хранить ненужные мне данные )))....
Вот код, который используется в kohana (один из вариантов xss_clean)
$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);
#5
Posted 12 March 2009 - 02:11 PM

А то я проект собираюсь сдвать, там это есть, но примитивно, без отлова экзотики типа <span style="width: expression(alert('Ping!'));"></span>
я о таком даже не знал

#6
Posted 12 March 2009 - 07:01 PM
#7
Posted 13 March 2009 - 01:56 AM
а вообще, так, по хорошему - надо бы написать класс который на себя возьмет обработку этих запросов. А то для такого фреймворка код типа $_POST['lalala'] не оч красиво.. лучше бы что-то типа Yii::request()->lalala или на подобии...
#8
Posted 13 March 2009 - 02:06 AM
#9
Posted 13 March 2009 - 02:16 AM
2) А что межает наследовать класс запроса и повесить по событию начала обработки обработку данных? Или можно не морочиться с наследованием, а прицепить поведение (Behaviour), которое приаттачится к событиям и будет обрабатывать вход с помощью того же CtmlPurifier
3) Между прочим, заюзать CHtmlPurifier в фильтре - вообще запросто. Только проблема - фильтр надо будет в каждом контроллере прописывать. Хотя может это и удобно, может ыть будут действия, где фильтрация не понадобится, их можно добавить в исключения фильтра
#10
Posted 13 March 2009 - 02:21 AM
Quote
Не дочитал, даже писать ниче не надо. Что медленно - так в доках написано:
Quote
Сохраняем перед вставкой в БД и все дела.
Но можно, конечно, написать что-то типа того что Андрей показал, наверное быстрее будет

#11
Posted 13 March 2009 - 02:51 AM
<?php
/**
* @author Opeykin A. <andrey.opeykin.ru> <aopeykin@gmail.com>
* @version 0.0.1
* @package filters
*
* Фильтр предназначен для фильтрации входных данных, c целью предотвратить xss атаки.
* Для фильтрации используются регулярные выражения из фреймворка Kohana 2.3.1
* @example
*
* public function filters()
* {
* return array(
* array('application.filters.XssFilter',
* 'clean' => 'all'
* )
* );
*
* }
*
* В качетве параметра 'clean' могут быть:
* - 'all' - фильтруются GET,POST,COOKIE,FILES массивы;
* - '*' - аналог ALL;
* - так же возможно сочетание любых из параметров, например GET,COOKIE или POST,FILES
*/
class XssFilter extends CFilter
{
public $clean = 'all';
protected function preFilter($filterChain)
{
$this->clean = trim(strtoupper($this->clean));
$data = array(
'GET' => &$_GET,
'POST' => &$_POST,
'COOKIE' => &$_COOKIE,
'FILES' => &$_FILES
);
if($this->clean === 'ALL' || $this->clean === '*')
{
$this->clean = 'GET,POST,COOKIE,FILES';
}
$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;
}
protected function postFilter($filterChain)
{
// logic being applied after the action is executed
}
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;
}
// xss_clean function from Kohana framework 2.3.1
$data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data);
$data = preg_replace('/(&#*w+)[x00-x20]+;/u', '$1;', $data);
$data = preg_replace('/(&#x*[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;
}
}
?>
а вот тут (http://andrey.opeyki...yii-xss-filter/) маленькая статья про фильтры в Yii и в частности про этот xss-фильтр....
#13
Posted 13 March 2009 - 03:50 AM

к стати, а можно фильтр повесить на модуль? чето лень в каждый контроллер пихать фильтр
#14
Posted 13 March 2009 - 04:11 AM
Quote

к стати, а можно фильтр повесить на модуль? чето лень в каждый контроллер пихать фильтр
я тоже думал над этим вопросом....помню очень давно, когда я пытался учить Java и в частности сервлеты - там тоже были фильтры, которые настраивались в конфигурационном файле (т.е. можно было указать правила, что-то типа роутинга в Yii, например можно было "сказать" так : для всех УРЛ-ов, начинающихся с "admin" - необходимо выполнить фильтр XssClean). Как мне кажется в Yii этого нет.....Было бы не плохо эсли бы кто-нибудь это сделал

#15
Posted 13 March 2009 - 04:53 AM
Я еще не тестил, но то что есть - это круто
