Boroda aka Hamster (fantaseour) wrote,
Boroda aka Hamster
fantaseour

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

Даже в весьма средней по размеру системе внесение изменений в отдельные компоненты может привести к наведенным эффектам. Например включение экранирования символов декорирует данные, передаваемые в шаблон с помощью специальных объектов, и массивы становятся объектами с интерфейсом массива. Также добавление плагина против 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()
  )
);
Tags: development, php, symfony
Subscribe

  • (no subject)

    Я очень люблю конференции. Они зажигают в разработчике свечечку, которую он потом бережно несет в себе через весь год! Когда-то давно, я с завистью…

  • wordpress: php -> nodejs

    Хипстеры захватывают мир :) Не очень понятно, как этот переход отразится, на людях, которые ставят этот вордпресс на любой копеечный хостинг с…

  • ultimate php

    For those who asked how to get started testing PHP7. I have packaged up my dev environment in a Vagrant box: https://t.co/EOhyi17fPI— Rasmus…

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 8 comments