Как сделать JSON Vulnerability Protection в ответе сервера под Yii2

от автора

В AngularJS реализована поддержка JSON Vulnerability Protection, направленная на то, чтобы противодействовать ситуациям, когда злоумышленник может, при определённых условиях, превратить JSON в JSONP и выполнить какой-то код. В качестве меры противодействия на серверной стороне предлагается добавлять к JSON-данным такой префикс: )]}',

Под катом — моя короткая история генерации JSON-данных с префиксом. Но, я думаю, эта история так же хорошо иллюстрирует и более общий вопрос — как можно добавлять свои собственные форматы ответов сервера. В Yii Framework это делается довольно-таки просто — для этого достаточно описать в конфигурации, какой класс будет отвечать за генерацию ответа определённого формата.

Я начал с того, что добавил в конфигурацию (/путь_к_проекту/config/web.php — раздел components → response → formatters) новый тип ответа — «jsonvp», назначив для него класс, который я собираюсь создать.

<?php // . . . $config = [     // . . .     'components' => [         // . . .         'response' => [             'formatters' => [                 'jsonvp' => 'app\components\JsonVpResponseFormatter',             ],         ],     ],     // . . . ]; 

В классе yii\web\Response есть свойство $formatters, которое дополнится тем, что есть в конфигурации. И теперь, если в каком-то экшене задать Yii::$app->response->format = 'jsonvp';, то он будет использовать для форматирования ответа класс app\components\JsonVpResponseFormatter. Во фреймворке есть интерфейс yii\web\ResponseFormatterInterface, который регулирует правила написания таких классов, так что можно применить к моему новому классу этот интерфейс.

<?php namespace app\components;  use yii\helpers\Json; use yii\web\Response; use yii\web\ResponseFormatterInterface;  class JsonVpResponseFormatter implements ResponseFormatterInterface {     /**      * Format as Vulnerability Protected JSON.      * @param Response $response      */     public function format($response)     {         $response->getHeaders()->set('Content-Type', 'application/json; charset=UTF-8');         if ($response->data !== null) {             $response->content = ")]}',\n" . Json::encode($response->data);         }     } } 

Осталось только проверить функционал:

<?php namespace app\controllers;  use Yii; use yii\web\Controller;  /**  * site/* actions.  * @package app\controllers  */ class SiteController extends Controller {     /**      * Test JSON output      * @return array      */     public function actionJson()     {         Yii::$app->response->format = 'jsonvp';         return ['123', '456'];     } } 

При вызове http://localhost/index.php?r=site/json в браузере выводится такой результат:

)]}', ["123","456"] 

Заключение

С помощью такого нехитрого способа можно создавать собственные форматы ответов. Например, как описано выше, — JSON с префиксом, позволяющим защититься от уязвимости. К сожалению, в книге рецептов по фреймворку на текущий момент нет описания того, как создавать собственные форматы ответов, хотя раздел и помечен меткой «TBD». Надеюсь, кому-то эта статья поможет. Удачи!

ссылка на оригинал статьи http://habrahabr.ru/post/256213/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *