Как и где может применяться защита XSS в Laravel?

Интересно, как (если так или иначе) защита XSS предоставляется в Laravel. Я не мог найти ничего об этом в документации.

проблема

Я использую метод create() Eloquent для вставки данных в базу данных (в моделях задаются $fillable / $guarded ). Как оказалось, я могу свободно помещать что-то вроде этого в текстовый ввод любой формы:

 <script>alert('Hacking Sony in 3...2...')</script> 

и значение будет вставлено в базу данных. Затем, когда его echo -сигнал – отображается предупреждение.

Возможные решения

Теперь, Laravel – действительно хорошая структура, поэтому я предполагаю, что должно быть что-то, что помешало бы XSS из коробки. Однако я не могу понять, что это такое.

Если я ошибаюсь, каков оптимальный способ решения проблемы?

  • Я использую фэнтезийную проверку правильности, чтобы запретить использование определенных символов?
  • Я использую mysql_real_escape_string() для каждого используемого mysql_real_escape_string() Input::get() ?
  • У меня strip_tags() ?

Недостаточно экранирования уровня экрана

Я знаю, что могу использовать тройные фигурные скобки Blade для исключения строк в представлениях, но это не главное. Мне гораздо больше смысла не позволять этим проницательным ублюдкам в базу данных в первую очередь.

Кто-нибудь столкнулся с этой проблемой уже?

Мне гораздо больше смысла не позволять этим проницательным ублюдкам в базу данных в первую очередь.

На самом деле – это не так.

Причина, по которой XSS обрабатывается только клиентом, заключается в том, что атаки XSS являются проблемой вывода . Нет угрозы безопасности, если вы храните <script>alert('Hacking Sony in 3...2...')</script> в вашей базе данных – это просто текст – это ничего не значит.

Но в контексте вывода HTML – тогда текст имеет смысл, и поэтому именно там должна произойти фильтрация.

Также – возможно, что атака XSS может быть отраженной атакой, где отображаемые данные не поступают из базы данных, а из другого источника. т.е. загруженный файл, URL-адрес и т. д. Если вы не можете отфильтровать все различные входные адреса, вы рискуете потерять что-то.

Laravel поощряет вас избегать выхода, независимо от того, откуда он появился. Вы должны явно отображать нефильтрованные данные по определенной причине – и только если вы уверены, что данные получены из надежного источника (т. Е. Из вашего собственного кода, а не из пользовательского ввода).

ps В Laravel 5 по умолчанию {{ }} выйдет весь выход, что подчеркивает важность этого.

Редактирование: вот хорошее обсуждение с дальнейшими соображениями о том, почему вы должны фильтровать вывод, а не вводить: html / XSS escape на входе и выходе

Насколько я знаю, «официальная» позиция Laravel заключается в том, что наилучшая практика предотвращения XSS заключается в том, чтобы избежать выхода . Таким образом, {{{ }}} .

Вы можете дополнить выходное экранирование через входную санитарию с помощью Input::all() , strip_tags() и array_map() :

 $input = array_map('strip_tags', \Input::all()); 

Я исследовал защиту Laravel {{{...}}} против атаки xss. Он просто использует htmlentities() образом: htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false); Это защитит вас от xss, только если вы используете его правильно, значит, не используйте его в определенных тегах HTML, потому что это приведет к возможности атаки XSS. Например:

 $a = htmlentities('javascript:alert("xss")', ENT_QUOTES, 'UTF-8', false); echo '<a href="'.$a.'">link</a>'; 

В этом случае он уязвим для xss.

Вы также фильтруете ввод перед валидацией, например: Сначала создайте /app/Common/Utility.php

 <?php namespace App\Common; use Illuminate\Support\Facades\Input; class Utility { public static function stripXSS() { $sanitized = static::cleanArray(Input::get()); Input::merge($sanitized); } public static function cleanArray($array) { $result = array(); foreach ($array as $key => $value) { $key = strip_tags($key); if (is_array($value)) { $result[$key] = static::cleanArray($value); } else { $result[$key] = trim(strip_tags($value)); // Remove trim() if you want to. } } return $result; } } 

И используйте в своем контроллере, как это

 use App\Common\Utility; public function store() { Utility::stripXSS(); // Remaining Codes } 

Этот код очистит ваш вход до проверки

Пакет laravelgems / blade-escape расширяет Blade, добавляя различные стратегии / директивы побега – @text , @attr , @css , @js , @param

Пример:

 <style> .userPrefix:before { content: "@css($content)"; } </style> <div> <label class="userPrefix">@text($label)</label> <input type="text" name="custom" value="@attr($value)"/> </div> <a href="/profile?u=@param($username)">Profile</a> <button onclick="callMyFunction('@js($username)');">Validate</button> <script> var username = "@js($username)"; </script> 

Прочтите их README. XSS очень сложный, есть много контекстов и подходов.

Страница тестирования – http://laragems.com/package/blade-escape/test