?

Log in

No account? Create an account
Craftman

Симфонические заметки

Даже в весьма средней по размеру системе внесение изменений в отдельные компоненты может привести к наведенным эффектам. Например включение экранирования символов декорирует данные, передаваемые в шаблон с помощью специальных объектов, и массивы становятся объектами с интерфейсом массива. Также добавление плагина против CDRF ломает работу с AJAX.

Пусть у нас есть объект $user, который может выдать в виде массива список ролей, которыми обладает. Конечно правильно дать возможность объекту юзеру определить обладает ли он заданной ролью через вызов

$user->hasRole($role)

Однако, если мы торопились и сделали эту проверку в виде

in_array($role,$user->getRoles())

то такая конструкция в шаблоне после включения экранирования перестанет работать. Поскольку объект $user будет задекорирован объектом, который будет экранировать данные, возвращаемые методами оригинального объекта. И вызов

$user->getRoles()

вернет не массив, а объект, который обладает интерфейсом массива, но с которым не работает in_array(). Для доступа к оригинальному объекту используется $sf_data->getRaw():

$sf_data->getRaw('user')->getRolesArray()

В данном примере конечно же правильнее унести эту конструкцию в модель целиком.

Также надо не забыть отключить экранирование, там, где оно не нужно, например в почте.

Против неприятной уязвимости CDRF существует плагин, который ко всем формам добавляет скрытое поле со значением, зависящим от сессии и потом при сабмите формы проверяет это значение. Мне не очень нравится, как он делает эту добавку -- это реализовано в виде фильтра и просто делается замена тэга формы с помощью регулярного выражения.

Поскольку заменяются только формы, в скрипт вызова AJAX компонентов токен не добавляется и AJAX перестает работать.

На странице плагина есть патч для Ajax.Autocompleter. Я по аналогии написал патч для Ajax.Updater

//добавляем в конец метода execute
$response->setContent(
  
preg_replace('#(new Ajax.Updater\()(\'[\w|\d|_]+)(\', )(\'\/[\w|\d|\-|_|\/|\.]+)#i',
               
'$1$2$3$4/_csrf_token/' .md5($secret.session_id()). '$7'
               
$response->getContent()
  )
);

Comments

А в рельсах тоже внесли authenticity_token. Против каких атак это?

P.S. Я полностью отказался от прототайпа и перешёл на jQuery. Сильно удобнее.

(Anonymous)

Это против атак вида зашел неразлогиненный админ на сайт Васи Пупкина. А Вася не только знал, что к нему придет неразлогиненный админ (ну например послал админу по почте ссылку "смотри какие деффки"), но и еще знал как устроена форма смена пароля в атакуемой системе. И на своем сайтике воспроизвел эту форму, и с помощью джава скрипта засабмиттил.

для атакуемой системы это выглядит как нормальное действие от лица админа.

Защищаются добавкой токена -- который зависит от сессии юзера. И вася хакер токена этого знать не может.

Ну понятно что этот тип уязвимостей имеет много разных вариаций (например не форму а просто картинку с нужным урлом в атакуемой системе, это если у нас в системе что-то меняется кликом на урл, что вообще-то не гуд), но суть вот такая.
надо подетальнее почитать.
Это я разлогинился :) прям в тему как бы :)
Все хотел спросить про jQuery. А extJS не пробовал использовать?
Ещё не пробовал
Вынужден признаться что этого языка я просто не понимаю. "экранирование данных передаваемых в шаблон"... нет, я не возражаю, но констатирую факт.
Можно попробую объяснить?

Экранирование это перевод строки в вид безопасный для html. Т.е. < должна стать &lt;, & -- &amp; и т.д.

Тут имеется подход такой, что в шаблон передаются подготовленный набор переменных (иногда это называется push подход, в отличие от pull-шаблонов, которые запрашивают данные у системы сами). Эти переменные выводятся, как есть, простыми конструкциями вроде <?php echo $message; ?> или <?php echo $user->getName(); ?>.

Данные выводимые в шаблоне могут содержать в себе опасные для html символы от просто скобок и амперсандов, до всяких XSS конструкций. Поэтому система старается обезопасить программера от ошибки "забыл сконвертировать данные в html сущности" (т.е. забыл проэкранировать). Для этого все, что едет в шаблон декорируется объектами, которые перехватывают геттеры и обращения к элементам массива и отдают безопасный контент. Если нужны неэкранированные данные, их нужно специально запросить, как в примере, который я привел.

А как называете такую операцию вы?