Интересно, как (если так или иначе) защита 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