Интересно, как (если так или иначе) обеспечивается защита XSS в Laravel. Я не мог найти ничего об этом в документации.
проблема
я использую Красноречивый-х create()
способ вставить данные в базу данных ($fillable
/$guarded
свойства устанавливаются в моделях). Как оказалось, я могу свободно поместить что-то подобное в текстовом поле любой формы:
<script>alert('Hacking Sony in 3...2...')</script>
и значение будет вставлено в базу данных. Тогда, когда echo
ing it — предупреждение показывается.
Возможные решения
Теперь Laravel — действительно хороший фреймворк, поэтому я бы предположил, что должен быть чем-то, чтобы предотвратить XSS из коробки. Тем не менее, я не могу узнать, что это такое.
Если я не прав, каков оптимальный способ решить проблему?
mysql_real_escape_string()
на каждом Input::get()
Я использую?strip_tags()
?Экранирования на уровне просмотра недостаточно
Я знаю, что могу использовать Blade’s тройные фигурные скобки избегать строк в представлениях, это не главное. Для меня гораздо больше смысла не пускать этих подлых ублюдков в базу данных.
Кто-нибудь уже сталкивался с этой проблемой?
Для меня гораздо больше смысла не пускать этих подлых ублюдков в базу данных.
На самом деле — это не так.
Причина того, что XSS обрабатывается только блейдом, заключается в том, что атаки XSS являются выход проблема. Там нет угрозы безопасности, если вы храните <script>alert('Hacking Sony in 3...2...')</script>
в вашей базе данных — это просто текст — это ничего не значит.
Но в контексте вывода HTML — тогда текст имеет значение, и поэтому именно здесь должна происходить фильтрация.
Также — возможно, что атака XSS может быть отраженной атакой, когда отображаемые данные поступают не из базы данных, а из другого источника. т.е. загруженный файл, URL и т. д. Если вам не удастся отфильтровать все различные местоположения ввода — вы рискуете что-то упустить.
Ларавел призывает вас сбежать все вывод, независимо от того, откуда он взялся. Вы должны явно отображать нефильтрованные данные по определенной причине — и только если вы уверены, что данные получены из надежного источника (т. Е. Из вашего собственного кода, а не из пользовательского ввода).
постскриптум В Laravel 5 по умолчанию {{ }}
будет избегать всех выходных данных — что подчеркивает важность этого.
Изменить: здесь хорошее обсуждение с дополнительными пунктами о том, почему вы должны фильтровать вывод, а не ввод: html / XSS escape на входе против выхода
Насколько я знаю, «официальная» позиция Laravel такова, что Лучшая практика по профилактике XSS — бежать выход. Таким образом, {{{ }}}
,
Вы можете дополнение выход, выходящий через вход санитария с Input::all()
, strip_tags()
, а также array_map()
:
$input = array_map('strip_tags', \Input::all());
Я проверил защиту Ларавела {{{...}}}
против атаки 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, добавляя различные экранирующие стратегии / директивы — @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
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);
}
}