Есть ли хороший «Laravel-способ» избежать html при возврате результатов json?

#php #laravel #datatables #xss

#php #laravel #таблицы данных #xss

Вопрос:

Я чувствую, что это должно быть общей проблемой, но я не смог найти на нее ответ. Шаблоны блейда упрощают экранирование html {{ $variable }} , но для вывода json в ajax-запрос — не так много.

Естественно, я работаю с приложением, которое выполняет множество вызовов ajax для введенных пользователем данных и возвращает результаты в формате JSON клиенту, который отображает их в формате jQuery DataTable. Итак, рассмотрим этот сценарий:

 $contacts = Contact::whereUserId(Auth::id())
                ->select('id', 'first_name', 'last_name', 'email', 'age')
                ->get();

return response()->json($contacts);
  

Я хочу избежать этих полей имен для внедрения html / script, прежде чем отображать их в таблице данных, например имени и фамилии. Единственный способ, который я могу придумать, чтобы сделать это, — это перебрать каждую строку в коллекции, и для каждого, перебрать каждое поле, и если это строка, использовать e() ее.

Есть ли что-то в фреймворке Laravel для обработки этого процесса? Или хорошая упаковка? Я бы предпочел не делать этого toJson() при каждом запуске, так как могут быть случаи, когда я не хочу это запускать, или, например, если это вызов API и мне нужно вернуть необработанные данные json.

Есть какой-нибудь совет? В настоящее время я работаю над Laravel 5.2.

Для справки, только несколько моих полей должны содержать html.

ОБНОВЛЕНИЕ: как указано в комментариях, я использую таблицы данных. В настоящее время я использую render опцию, которая является просто закрытием, для каждого столбца, который я хочу экранировать, и использую функцию strip tags / html entities на основе javascript. Я вроде как чувствовал, что делаю это неправильно, что должна быть какая-то функция для автоматического выполнения этого в среде Laravel, учитывая, насколько она распространена, а также способ настройки шаблонов блейдов, но считается ли это идеальным решением?

Комментарии:

1. Если вы возвращаете этот JSON клиенту Javascript, клиенту Javascript нужно беспокоиться о правильной обработке HTML в нем. С помощью Javascript, который вы обычно используете elem.textContent = someContent , и все. Он будет обрабатывать содержимое как текст DOM , а не HTML, и экранирование не требуется. Экранирование на сервере — неподходящее место для этого.

2. Наконец, @deceze для победы. В этом месте слишком много людей, которые не понимают, куда должен идти экранирование. Необходимо сделать этот комментарий ответом, чтобы его можно было принять.

3. Ага. Я полагал, что это было бы небезопасно каким-то образом, избегая его на стороне клиента.

4. jQuery DataTables не экранирует HTML, поэтому, если поле содержит <b>Text</b> его, оно будет выделено жирным шрифтом в таблице по умолчанию.

5. @Gyrocode.com Я знаю, мне пришлось бы добавить render опцию к каждому столбцу, который я хотел экранировать, и запустить экранирующую функцию. Но я не был уверен, что это действительно лучший способ справиться с этим в масштабах всего приложения.

Ответ №1:

jQuery DataTables не экранирует HTML, поэтому, если поле содержит <b>Text</b> его, оно будет выделено жирным шрифтом в таблице по умолчанию.

Вы можете закодировать HTML-объекты в своем ответе, используя приведенный ниже код:

 return response()->json(array_map('e', $contacts->toArray()));
  

Если вы используете таблицы данных Yajra для Laravel, у него есть escapeColumns() метод, который вы можете использовать для экранирования HTML-объектов в некоторых или во всех столбцах. Например:

 return Datatables::of($contacts)
   ->escapeColumns(['first_name', 'last_name')
   ->make(true);