Как и где может применяться защита XSS в Laravel?
Интересно, как (если так или иначе) обеспечивается защита XSS в Laravel. Я не мог найти ничего об этом в документации.
проблема
Я использую метод Eloquent create()
для вставки данных в базу данных (в моделях установлены свойства $fillable
/$guarded
). Как оказалось, я могу свободно поместить что-то подобное в любой форме ввода текста:
<script>alert('Hacking Sony in 3...2...')</script>
и значение будет вставлено в базу данных. Тогда, когда echo
ИНГ это - предупреждение показывается.
Возможные решения
Теперь Laravel - действительно хороший фреймворк, поэтому я предполагаю, что должно быть что-то, чтобы предотвратить XSS из коробки. Тем не менее, я не могу узнать, что это такое.
Если я не прав, каков оптимальный способ решить проблему?
- Использую ли я необычную проверку регулярных выражений, чтобы запретить определенные символы?
- Я использую
mysql_real_escape_string()
на каждом Input::get()
я использую? - Должен ли я
strip_tags()
?
Экранирования на уровне просмотра недостаточно
Я знаю, что могу использовать тройные фигурные скобки Blade, чтобы убрать строки в представлениях, но это не главное. Для меня гораздо больше смысла не пускать этих подлых ублюдков в базу данных.
Кто-нибудь уже сталкивался с этой проблемой?
Ответы
Ответ 1
Мне гораздо больше смысла не позволять этим скрытым ублюдкам в базу данных в первую очередь.
Собственно - это неверно.
Причина, по которой XSS обрабатывается только клиентом, заключается в том, что атаки XSS являются проблемой вывода. Нет угрозы безопасности, если вы храните <script>alert('Hacking Sony in 3...2...')</script>
в своей базе данных - это просто текст - это ничего не значит.
Но в контексте вывода HTML - тогда текст имеет смысл, и поэтому именно там должна произойти фильтрация.
Также - возможно, что атака XSS может быть отраженной атакой, когда отображаемые данные не поступают из базы данных, а из другого источника. то есть загруженный файл, URL-адрес и т.д. Если вы не можете отфильтровать все различные местоположения ввода - вы рискуете потерять что-то.
Laravel поощряет вас избегать выхода, независимо от того, откуда он появился. Вы должны явно отображать нефильтрованные данные по определенной причине - и только если вы уверены, что данные получены из надежного источника (т.е. Из вашего собственного кода, никогда не из пользовательского ввода).
p.s. В Laravel 5 по умолчанию {{ }}
выйдет весь выход, что подчеркивает важность этого.
Изменить: вот хорошая дискуссия с дальнейшими соображениями о том, почему вы должны фильтровать вывод, а не вводить: html/XSS escape на входе и выходе
Ответ 2
Насколько я знаю, "официальная" позиция Laravel заключается в том, что Лучшая практика предотвращения XSS заключается в том, чтобы избежать выхода. Таким образом, {{{ }}}
.
Вы можете добавить выходное экранирование через входную санитарию с помощью Input::all()
, strip_tags()
и array_map()
:
$input = array_map('strip_tags', \Input::all());
Ответ 3
Я исследовал защиту 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.
Ответ 4
Вы также фильтруете ввод перед валидацией, например: Сначала создайте /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
}
Этот код очистит ваш вход до проверки
Ответ 5
Пакет 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="/[email protected]($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
Ответ 6
class XSSProtection
{
/**
* The following method loops through all request input and strips out all tags from
* the request. This to ensure that users are unable to set ANY HTML within the form
* submissions, but also cleans up input.
*
* @param Request $request
* @param callable $next
* @return mixed
*/
public function handle(Request $request, \Closure $next)
{
if (!in_array(strtolower($request->method()), ['put', 'post'])) {
return $next($request);
}
$input = $request->all();
array_walk_recursive($input, function(&$input) {
$input = strip_tags($input);
});
$request->merge($input);
return $next($request);
}
}
Ответ 7
Посмотрите приведенную ниже ссылку, она уберет все теги сценариев или любые ненужные теги без экранирования тегов HTML Ссылка на очиститель HTML