Yii Framework Forum: Фильтрация POST&GET или xss защита - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Фильтрация POST&GET или xss защита Rate Topic: -----

#1 User is offline   Digital God 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 178
  • Joined: 30-January 09

Posted 12 March 2009 - 01:28 AM

Собственно наткнувшись на основном форуме на топик о фильтрации POST запросов у меня возник вопрос. А как в Yii фильтровать данные? Почти во всех фреймворках есть встроенные классы xss защиты.. в Yii нету.
qiang советует напрямую заюзать filter_input, товарищ jimezam предложил связку Yii с Kohana, чтобы пользоваться функциями Kohan'ы...

Последний вариант кажется удобным, но как-то не хочется в проект еще и кохану втыкать...

Может у кого есть идеи на этот счет? Или готовые варианты?
0

#2 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 12 March 2009 - 06:59 AM

я сейчас как раз пишу такой фильтр (именно как фильтр будет работать)...
Начинку (регулярки, которые все и фильтруют - взял их Kohana 2.3.1)...
Думаю за выходные допишу (к сожалению раньше не получится)...
0

#3 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 12 March 2009 - 11:06 AM

Андрей, если закончишь и выложишь как экстеншн - большой респект :)

А поподробнее про данный варинат защиты где почитать, а то по ходу у мен в образовании пробел... Ну что такое XSS я знаю, а вот как защищаться - не.
0

#4 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

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: exp​ression(alert('Ping!'));"></span>
$data = preg_replace('#(<[^>]+?)style[x00-x20]*=[x00-x20]*[`'"]*.*?exp​ression[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);



0

#5 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 12 March 2009 - 02:11 PM

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

#6 User is offline   creocoder 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 199
  • Joined: 09-March 09
  • Location:*.php

Posted 12 March 2009 - 07:01 PM

Нужно ли изобретать велосипед или проще почитать досконально доку? Yii содержит "из коробки" компонент CHtmlPurif ier, который в свою очередь является оберткой для библиотеки HTML Purifier. Библиотека предназначена для защиты от XSS атак. Компонент работает как фильтр и как виджет.
0

#7 User is offline   Digital God 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 178
  • Joined: 30-January 09

Posted 13 March 2009 - 01:56 AM

Ну разговор шел больше не о том КАК обрабатывать, а именно чтобы встроить в Yii фильтр. Мне вот влом на каждый GET и POST запрос вешать html purifier вручную... хочется чтобы он отрабатывал сам...

а вообще, так, по хорошему - надо бы написать класс который на себя возьмет обработку этих запросов. А то для такого фреймворка код типа $_POST['lalala'] не оч красиво.. лучше бы что-то типа Yii::request()->lalala или на подобии...
0

#8 User is offline   Digital God 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 178
  • Joined: 30-January 09

Posted 13 March 2009 - 02:06 AM

И если мне память не изменяет - CHtmlPurifier используется для обработки данных перед выводом пользователю, а не перед вставкой в базу. это раз. и во вторых - он громоздкий и тормознутый... имхо не лучший вариант при оптимизации скорости...
0

#9 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 13 March 2009 - 02:16 AM

1) Ну я думаю, что его можно юзать и для обработки перед вставкой в базу (доки еще не читал)
2) А что межает наследовать класс запроса и повесить по событию начала обработки обработку данных? Или можно не морочиться с наследованием, а прицепить поведение (Behaviour), которое приаттачится к событиям и будет обрабатывать вход с помощью того же CtmlPurifier
3) Между прочим, заюзать CHtmlPurifier в фильтре - вообще запросто. Только проблема - фильтр надо будет в каждом контроллере прописывать. Хотя может это и удобно, может ыть будут действия, где фильтрация не понадобится, их можно добавить в исключения фильтра
0

#10 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 13 March 2009 - 02:21 AM

Quote

Компонент работает как фильтр и как виджет.

Не дочитал, даже писать ниче не надо. Что медленно - так в доках написано:

Quote

Note: since HTML Purifier is a big package, its performance is not very good. You should consider either caching the purification result or purifying the user input before saving to database.

Сохраняем перед вставкой в БД и все дела.

Но можно, конечно, написать что-то типа того что Андрей показал, наверное быстрее будет :)
0

#11 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

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('&amp;','&lt;','&gt;'), array('&amp;amp;','&amp;lt;','&amp;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: exp​ression(alert('Ping!'));"></span>
                $data = preg_replace('#(<[^>]+?)style[x00-x20]*=[x00-x20]*[`'"]*.*?exp​ression[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-фильтр....
0

#12 User is offline   Digital God 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 178
  • Joined: 30-January 09

Posted 13 March 2009 - 03:43 AM

Респект тебе :) ща заюзаю ;)
0

#13 User is offline   Digital God 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 178
  • Joined: 30-January 09

Posted 13 March 2009 - 03:50 AM

Работает  ;D
к стати, а можно фильтр повесить на модуль? чето лень в каждый контроллер пихать фильтр
0

#14 User is offline   xomaa 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 82
  • Joined: 17-January 09

Posted 13 March 2009 - 04:11 AM

Quote

Работает  ;D

к стати, а можно фильтр повесить на модуль? чето лень в каждый контроллер пихать фильтр

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

#15 User is offline   KJedi 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 381
  • Joined: 19-October 08
  • Location:Nikolaev, Ukraine (Europe)

Posted 13 March 2009 - 04:53 AM

Можно контроллеры модуля наследовать от одного базового контроллера, в котором прописать фильтр.

Я еще не тестил, но то что есть - это круто :) Молодец!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users