Как экранировать вывод в шаблонах

Как экранировать вывод в шаблонах

При генерировании HTML из шаблона, всегда существует риск того, что переменная шаблона может вывести ненамеренный HTML или опасный код клиентской стороны. Результатом будет то, что динамеческое содержание может поломать HTML страницы результата, или позволить злому пользователю выполнить межсайтовый скриптинг (XSS-атаку). Рассмотрите этот классический пример:

  • Twig
    1
    Hello {{ name }}
    
  • PHP
    1
    Hello <?php echo $name ?>
    

Представьте, что пользователь вводит следующий код в качестве своего имени:

1
<script>alert('hello!')</script>

Без какого-либо экранирования вывода, результирующий шаблон приведёт к вызову окна предупредительного сообщения JavaScript:

1
Hello <script>alert('hello!')</script>

И хоть это и выглядит безобидно, если пользователь может зайти так далеко, то тот же пользователь так же может написать Java-script, выполняющий злоумышленные действия внутри безопасной зоны незнающего легального пользователя.

Решением этой проблемы является экранирование вывода. С включенным экранированием вывода, тот же шаблон будет отображаться без вреда, и буквально выводить на экран тег script:

1
Hello &lt;script&gt;alert(&#39;hello!&#39;)&lt;/script&gt;

Системы шаблонов Twig и PHP подходят к проблеме по-разному. Если вы используете Twig, то экранирование вывода влючено по умолчанию и вы защищены. В PHP, экранирование вывод не автоматическое, что означает, что вам вручную нужно будет экранировать там, где это необходимо.

Экранирование вывода в Twig

Если вы используете шаблоны Twig, тогда экранирование вывода включено по умолчанию. Это означает, что вы защищены сразу после установки от ненамеренных последствий кода, отправленного пользователем. По умолчанию, экранирование вывода предполагает, что содержимое экранируется для вывода HTML.

В некоторых случаях, вам понадобится отключить экранирование вывода, когда вы отображаете переменную, которой можно доверять и которая содержит разметку, которую не стоит экранировать. Представьте, что пользователи-администраторы могут писать статьи, содержащие HTML-код. По умолчанию, Twig будет экранировать тело статьи.

Чтобы отобразить её нормально, добавьте фильтр raw:

1
{{ article.body|raw }}

Вы также можете отключить экранирование вывода внутри зоны {% block %}, или во всём шаблоне. Чтобы узнать больше информаии, смотрите Экранирование вывода в документации Twig.

Экранирование вывода в PHP

Экранирование вывода не автоматическое при использовании PHP-шаблонов. Это означает, что разве что вы ясно не выберете экранировать переменную, то вы не защищены. Чтобы использовать экранирование вывода, используйте специальный метод просмотра escape():

1
Hello <?php echo $view->escape($name) ?>

По умолчанию, метод escape() предполагает, что переменная отображается в HTML-контексте (и поэтому переменная экранируется для безопасности HTML). Второй аргумент позволяет вам изменить контекст. Например, чтобы вывести что-то в строке Java-скрипта, используйте контекст js:

1
var myMsg = 'Hello <?php echo $view->escape($name, 'js') ?>';

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.