Все статьи

HTML Entities: как безопасно выводить спецсимволы на странице

В HTML символы <, > и & зарезервированы под разметку, но для русскоязычных сайтов есть и другая, менее очевидная причина использовать entity — это типографские кавычки-«ёлочки» и неразрывный пробел, без которых русский текст выглядит неряшливо.

«Ёлочки» вместо прямых кавычек

В русской типографике приняты кавычки-«ёлочки» — « и », а не прямые ". Их можно вставить как обычные символы Unicode (сайт в UTF-8 отобразит их без проблем) или как именованные entity &laquo; и &raquo; — это удобно, когда текст готовят в редакторе без лёгкого доступа к этим символам на клавиатуре, либо когда требуется совместимость со старыми шаблонизаторами, которые чувствительны к сырым многобайтовым символам в исходниках.

Неразрывный пробел — не совсем про экранирование, но рядом

Entity &nbsp; в русском вебе используют не только для вёрстки, но и по правилам типографики: неразрывный пробел ставят перед тире, между инициалами и фамилией, после предлогов из одной буквы («в», «к», «с»), чтобы они не оставались одни в конце строки. Формально это не про безопасность, но именно ради таких мелочей русскоязычные CMS и текстовые редакторы массово используют entity вместо литеральных символов.

Минимальный набор для экранирования разметки

  • <&lt; — чтобы не начался тег.
  • >&gt; — чтобы корректно закрыть текст после тега.
  • &&amp; — чтобы амперсанд не воспринимался как начало другого entity.
  • " и '&quot;, &#39; — обязательно внутри атрибутов в кавычках.

Наследие досовской и Windows-1251 эпохи

До повсеместного перехода на UTF-8 многие рунет-сайты хранили страницы в кодировке Windows-1251 или KOI8-R. При обмене данными между системами с разной кодировкой кириллица легко превращалась в «кракозябры», и числовые entity вида &#1057;&#1072;&#1081;&#1090; служили страховкой: числовой код символа Unicode не зависит от того, в какой кодировке хранится сама HTML-страница.

Связь с XSS

Большинство XSS-уязвимостей возникают именно потому, что введённый пользователем текст вставляют в HTML без экранирования. Если текст «<script>...</script>» вывести без преобразования в entity, браузер выполнит его как код. Экранирование — базовая, хоть и не единственная, мера защиты при выводе динамического контента.

Контекст имеет значение: текст против атрибута

Экранирования <, > и & достаточно для текста между тегами, но внутри атрибута в кавычках нужно дополнительно экранировать именно тот символ кавычек, который использован — двойные или одинарные. Если атрибут ограничен двойными кавычками, а в значении есть неэкранированная двойная кавычка, разметка «разорвётся» раньше, чем ожидалось.

Попробовать инструмент