Очистка ввода HTML с помощью Trix

У меня сейчас странная проблема, и я ищу любую информацию о том, как с этим справиться.

В настоящее время я принимаю ввод HTML с помощью редактора Basecamp Trix.

Когда я отправляю ввод в свое приложение Laravel, он сохраняется в моей базе данных как:

<div>&lt;script&gt;alert('test');&lt;/script&gt;</div>

Однако проблема в том, что когда я вставляю это в свойство Vue с помощью блейда Laravel, оно каким-то образом фактически преобразует его обратно в действительный HTML:

<reply :data-reply="{{ $reply }}"></reply>

Результат:

введите здесь описание изображения

Кажется, что Laravel преобразует теги script в действительный HTML, используя операторы Blade echo?

Мой вид:

{{ $reply }}

Результат:

{"id":63,"created_at":"2017-09-07 13:30:53","updated_at":"2017-09-07 13:35:05","user_id":1,"body":"<div><script>alert('test');<\/script><\/div>","options":null}

Проблема в том, что я не могу дезинфицировать это, потому что данные HTML на самом деле экранированы в моей базе данных, но когда Laravel преобразует мой ответ в JSON, он фактически не экранирует теги script и фактически запускается во Vue при использовании директивы v-html.

Я знаю, что не должен принимать пользовательский ввод при использовании директивы v-html, но мне нужна поддержка HTML для ответов, и я не могу дезинфицировать уже экранированный HTML в своем приложении Laravel.

У кого-нибудь есть идеи, как я могу каким-то образом очистить контент Трикс?


person Steve Bauman    schedule 07.09.2017    source источник
comment
попробовать <reply :data-reply="{!! $reply !!}"></reply> ?   -  person Quezler    schedule 07.09.2017


Ответы (1)


Хорошо, я поставил

<div>&lt;script&gt;alert('test');&lt;/script&gt;</div>

в поле электронной почты пользователя.

В Laravel я просто использую:

return view('welcome', ['user' => App\User::find(1)]);

ничего особенного в модели.

Мой взгляд выглядит так:

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<div id="el">{{ $user }}</div>
<script>
    user = JSON.parse(document.getElementById("el").innerHTML);
    console.log(user.name);
</script>
</body>
</html>    

и в консоли JS я получаю:

&lt;div&gt;&lt;script&gt;alert('test');&lt;/script&gt;&lt;/div&gt;

так что это не так, как в базе данных, но и не так, как вы показали.

person Marcin Nabiałek    schedule 07.09.2017
comment
На самом деле это не сработает, так как я передаю весь объект Reply, который является json_encoded Laravel, когда он проходит через обычные экранирующие скобки. Кроме того, теги {!! !!} ничего не экранируют, на самом деле все наоборот. Спасибо хоть! - person Steve Bauman; 07.09.2017
comment
@SteveBauman Извините, я неправильно понял ваш вопрос, я обновил свой ответ. - person Marcin Nabiałek; 07.09.2017
comment
На самом деле делает то же самое, по какой-то причине, когда модель ответа передается Vue с помощью тегов {{ }} laravel, он преобразует теги скрипта в теле ответа в действительный HTML: <div><script>alert('test');</script></div> - person Steve Bauman; 07.09.2017
comment
@SteveBauman Посмотрите на мое редактирование, вы уверены, что снова получаете правильный HTML? Я получаю прямо противоположное. Убедитесь, что это не Vue, который снова конвертирует его в HTML. - person Marcin Nabiałek; 07.09.2017
comment
Хмммм... Что отображается в реальном представлении для вашей пользовательской модели? Видите ли вы, преобразуются ли теги обратно в настоящие HTML-теги? Кстати, я использую Laravel 5.5, а у вас 5.5? - person Steve Bauman; 07.09.2017
comment
@SteveBauman Да, это 5.5, как видите, все сбежало. Пробовали ли вы использовать точно такой же код, как я показал на вашем компьютере, и проверить результат? - person Marcin Nabiałek; 07.09.2017
comment
Я попытаюсь! Кроме того, кажется, что я только что решил это, используя htmlentities в теле ответа, полученном сервером, например: $reply->body = htmlentities($request->body); Я также отправлю свои результаты с вашим предложением. - person Steve Bauman; 07.09.2017
comment
Я понимаю: {"id":4,"created_at":"2017-09-05 09:58:23","updated_at":"2017-09-07 14:53:51","deleted_at":null,"name":"<div><script>alert('test');<\/script><\/div>","email":"[email protected]"} - person Steve Bauman; 07.09.2017
comment
Давайте продолжим обсуждение в чате. - person Marcin Nabiałek; 07.09.2017