Привет всем!
Кто-нибудь занимался тем, чтобы подружить защиту от CSRF вкупе с запросами от Flash? Основная проблема такая: Flash не передает браузерные куки в HTTP запросе (YII_CSRF_TOKEN как раз таки и хранится в кукисах браузера) — это факт.
На ум приходят два решения и обхода такой проблемы:
1. Создать свой класс-потомок от CHttpRequest и сделать так, чтобы YII_CSRF_TOKEN хранился в сессии, а не в кукисах. Сессию восстановить по переданному session_id получается вполне. Возникает другой вопрос: почему YII_CSRF_TOKEN вообще всегда не хранить в сессии? Почему в Yii CSRF токен хранится именно в кукисах?
2. Просто самому ручками сохранить в сессии значение YII_CSRF_TOKEN при отдаче страницы с этой Флэшкой, а уже из восстановленной по session_id сессии получить этот YII_CSRF_TOKEN и сравнить с тем, что пришло от Флэшки.
Кто что думает? Какой метод более правилен и в целом приятнее?
Просто вырубать проверку CSRF токена как-то желания нет — зачем самому открывать потенциальные дыры в системе?
HTTP запрос от Flash и защита от CSRF — варианты решения
- resurtm
- Сообщения: 299
- Зарегистрирован: 2010.12.19, 09:13
- Откуда: Казахстан, Алма-Ата
- Контактная информация:
Re: HTTP запрос от Flash и защита от CSRF — варианты решения
Короче сделал гибридным методом.
Восстанавливаем сессию по переданному ее идентификатору в POST запросе, а также форсируем изменение CSRF токена в HttpRequest. Токен берем из сессии восстановленной, а не из POST запроса (как это делают многие).
Указываем в конфиге то, что HttpRequest у нас свой:
Виджет во вьюшке:
Сохраняем CSRF токен в сессии (изначально он хранится в кукисах). Делать это нужно в действии контроллера, которое отображает страницу с виджетом выше.
Наш новый класс HttpRequest. Пришлось извернуться с тем, что $_csrfToken в CHttpRequest приватен (ну оно и понятно, ситуация немного необычная).
Механизм валидации загрузки файлов и самой обработки загрузки файлов стандартный (http://www.yiiframework.com/wiki/2/how- ... ng-a-model). Полноценный пример могу сделать, если кто тоже столкнется с этим. Основное преимущество всех этих свистоплясок — это честная и правильная защита от CSRF при помощи токенов даже тогда, когда запрос осуществляется из Flash. Многие просто берут значение из $_POST, хотя это не есть безопасно.
Упоминаю теги на всякий случай для тех, кто будет искать: SWF Upload, Flash Upload, Uploadify, AJAX, upload, Flash, CSRF, token, Cookie, Cookies, Flash Cookies.
Восстанавливаем сессию по переданному ее идентификатору в POST запросе, а также форсируем изменение CSRF токена в HttpRequest. Токен берем из сессии восстановленной, а не из POST запроса (как это делают многие).
Код: Выделить всё
// Обработчик события onBeginRequest
public static function onBeginRequest()
{
if(isset($_POST['SESSION_ID'], $_POST[Yii::app()->request->csrfTokenName]))
{
$session=Yii::app()->session;
$session->close();
$session->sessionID=$_POST['SESSION_ID'];
$session->open();
Yii::app()->request->csrfToken=Yii::app()->session['csrfToken'];
Yii::app()->request->cookies[Yii::app()->request->csrfTokenName]=
new CHttpCookie(Yii::app()->request->csrfTokenName, Yii::app()->session['csrfToken']);
Yii::trace(var_export($_REQUEST, true), 'application.components.Helper');
}
}
Код: Выделить всё
// Конфиг приложения.
'components'=>array(
'request'=>array(
'class'=>'HttpRequest',
'enableCsrfValidation'=>true,
'enableCookieValidation'=>true,
),
),
Код: Выделить всё
<div class="button">
<?php $this->widget('ext.uploadify.MUploadify',array(
'model'=>$userProfile,
'attribute'=>'avatar',
'script'=>url('signup/avatarUpload', array('key'=>$userSignup->key)),
)); ?>
</div>
Код: Выделить всё
// сохраняем CSRF токен в сессии — понадобится позже
Yii::app()->session['csrfToken']=Yii::app()->request->csrfToken;
Код: Выделить всё
<?php
class HttpRequest extends CHttpRequest
{
protected $_customCsrfToken=null;
public function setCsrfToken($csrfToken)
{
$this->_customCsrfToken=$csrfToken;
}
public function getCsrfToken()
{
if($this->_customCsrfToken!==null)
return $this->_customCsrfToken;
return parent::getCsrfToken();
}
}
Упоминаю теги на всякий случай для тех, кто будет искать: SWF Upload, Flash Upload, Uploadify, AJAX, upload, Flash, CSRF, token, Cookie, Cookies, Flash Cookies.
Последний раз редактировалось resurtm 2011.11.11, 21:03, всего редактировалось 1 раз.
- resurtm
- Сообщения: 299
- Зарегистрирован: 2010.12.19, 09:13
- Откуда: Казахстан, Алма-Ата
- Контактная информация:
Re: HTTP запрос от Flash и защита от CSRF — варианты решения
А, ну и патч в MUploadify (http://www.yiiframework.com/extension/muploadify/). Автор возможно внесет свои изменения чуть позже:
Код: Выделить всё
protected function setBaseOptions(){
// ...
//$this->_options['scriptData'][$this->sessionKey]=session_id();
$this->_options['scriptData'][$this->sessionKey]=Yii::app()->session->sessionID;
if(Yii::app()->request->enableCsrfValidation)
$this->_options['scriptData'][Yii::app()->request->csrfTokenName]=Yii::app()->request->csrfToken;
}