CakePhp: избегайте XSS-атак, сохраняя простоту использования торта - PullRequest
2 голосов
/ 22 июля 2011

Одна из вещей, которые мне нравятся в cakePhp, это то, что мы можем легко создать сгенерированную отредактированную форму, которая позволяет нам сохранять.

например. в контроллере:

function add() {
        if (!empty($this->data)) {
            $this->Post->create();
            if ($this->Post->save($this->data)) {
                $this->Session->setFlash(__('The post has been saved', true));
                $this->redirect(array('action' => 'index'));
            } else {
                $this->Session->setFlash(__('The post could not be saved. Please, try again.', true));
            }
        }
        $users = $this->Post->User->find('list');
        $this->set(compact('users'));
    }

Проблема в том, что наши поля уязвимы для XSS (межсайтовый скриптинг). Я знаю способ «Sanitize :: Clean», но у меня есть проблема с этим: это означает, что мы должны сделать это на всех полях, прежде чем сохранить объект. А что если однажды мы добавим одно поле? Мы должны пойти на весь наш код, чтобы проверить, что мы его дезинфицировать ?? Можно ли как-то сказать «очистить этот объект перед сохранением», не указывая никаких полей?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 22 июля 2011

Как правильно заявляет andreas, общепринятой практикой является сохранение исходного HTML-кода и его обработка только при выводе (сохраняя исходный ввод, это может помочь, например, отслеживать, кто разместил вредоносный контент и т. Д.).

Для очистки в представлении вы должны использовать вспомогательную функцию CakePHP h($string), которая является сокращением для htmlspecialchars , которая сделает все попытки XSS полностью безвредными.

edit- это физически не удалит код XSS, а просто представит его таким образом, чтобы не повредить вашему приложению.

echo h('<script>alert("xss");</script>');

приведет к &lt;script&gt;alert(&#039;xss&#039;);&lt;/script&gt;

3 голосов
/ 22 июля 2011

Вы можете посмотреть beforeSave() метод для моделей

http://book.cakephp.org/view/1052/beforeSave

представленные данные доступны в массиве $this->data[$this->alias], поэтому вы можете

foreach($this->data[$this->alias] as $k => $v) {
   $this->data[$this->alias][$k] = Sanitize::clean($v);
}

Обычно вы хотите хранить все, что было отправлено пользователем в базу данных, и очищать его только тогда, когда вам нужно его отобразить, таким образом, вы все равно сохраняете исходное содержимое HTML (если оно действительно предназначено для ввода HTML (например, блог).post)).

Если вы хотите выполнить Sanitize перед отображением, вы можете сделать это с помощью afterFind(), чтобы вам не приходилось каждый раз вызывать Sanitize.

http://book.cakephp.org/view/1050/afterFind

function afterFind($results, $primary) {
   $toSanitize = array('field1', 'field2', 'field4');
   if(!empty($results[0])) {
      foreach($results as $i => $res) {
         foreach($toSanitize as $ts) {
            if(!empty($res[$this->alias][$ts])) 
               $results[$i][$this->alias][$ts] = Sanitize::clean($res[$this->alias][$ts]);
            }
         }
      }
   } else {

     foreach($toSanitize as $ts) {
        if(!empty($results[$ts])) 
           $results[$ts] = Sanitize::clean($results[$ts]);
        }
     }
   }

   return $results;
}
1 голос
/ 22 июля 2011

Может быть, вы могли бы выполнить очистку в методе afterFind модели.Это будет вызвано после поиска, который вы, вероятно, делаете перед отображением ваших данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...