Magento 2: безопасность шаблонов: какой метод использовать?

29

Я знаю, что в Magento 2 есть несколько методов для защиты шаблона:

  • $block->escapeHtml()
  • $block->escapeQuote()
  • $block->escapeUrl()
  • $block->escapeXssInUrl()

Но мне интересно, когда использовать каждый из этих методов?

Рафаэль в цифровом пианизме
источник

Ответы:

35

Методы экранирования во AbstractBlockвсех вызовах делегатов Magento\Framework\Escaper, так что вы найдете там обзор.

Давайте посмотрим на публичные методы и их документацию:

escapeHtml ()

/**
 * Escape string for HTML context. allowedTags will not be escaped, except the following: script, img, embed,
 * iframe, video, source, object, audio
 *
 * @param string|array $data
 * @param array|null $allowedTags
 * @return string|array
 */
public function escapeHtml($data, $allowedTags = null)

Это должен быть ваш метод экранирования по умолчанию для любого вывода. Соглашение состоит в том, что результат всех методов, которые не содержат "Html", должен быть экранирован.

escapeHtmlAttr ()

( начиная с Magento 2.2 )

/**
 * Escape a string for the HTML attribute context
 *
 * @param string $string
 * @param boolean $escapeSingleQuote
 * @return string
 */
public function escapeHtmlAttr($string, $escapeSingleQuote = true)

Используйте это для экранирования вывода в атрибуте HTML, например

title="<?php echo $block->escapeHtmlAttr($title) ?>"

Это будет экранировать HTML, но также и кавычки ( ")

По умолчанию он также экранирует одинарные кавычки, так что это тоже работает:

onclick="alert('<?php echo $block->escapeHtmlAttr($message) ?>')"

Установите для второго параметра значение false, если это нежелательно.

escapeUrl ()

/**
 * Escape URL
 *
 * @param string $string
 * @return string
 */
public function escapeUrl($string)

Это может быть использовано для вывода URL. Он будет применять экранирование HTML по умолчанию и дополнительно удаляет javascript:, vbscript:и data:. Если вы хотите запретить URL-адреса, подобные этим, в предоставленных пользователем ссылках, вы можете использовать метод.

До Magento 2.1 эта функция не была включена, и вам нужно было использовать escapeXssInUrl()вместо этого. Там не было никаких оснований для использования escapeUrl()на всех.

В противном случае просто используйте $block->escapeHtmlAttr()для URL-адресов.

encodeUrlParam ()

( начиная с Magento 2.2 )

/**
 * Encode URL
 *
 * @param string $string
 * @return string
 */
public function encodeUrlParam($string)

Это применяет кодировку URL к параметрам. Для внутренних URL-адресов вы всегда должны использовать getUrl(), где кодировка URL уже сделана для вас, так что это необходимо, только если вы вручную создаете внешний URL-адрес.

escapeJs ()

( начиная с Magento 2.2 )

/**
 * Escape string for the JavaScript context
 *
 * @param string $string
 * @return string
 */
public function escapeJs($string)

Кодируются символы Юникода для JavaScript, например , становится \u2665. Используйте его для экранирования вывода в строке JS . Для встроенного Javascript (то есть onclickатрибутов) вам все равно нужно позвонить escapeHtmlAttr().

Обратите внимание, что если вы используете json_encode(), он уже делает то же самое экранирование, в этом случае escapeJs()не должно использоваться.

escapeCss ()

( начиная с Magento 2.2 )

/**
 * Escape string for the CSS context
 *
 * @param string $string
 * @return string
 */
public function escapeCss($string)

Кодирует символы Юникода для CSS (см. escapeJs()), Например, для использования в contentатрибуте CSS.

Устаревшие методы (по состоянию на Magento 2.2):

  • escapeJsQuote: использовать escapeHtmlAttr()вместо
  • escapeXssInUrl: использовать escapeUrl()вместо
  • escapeQuote: использовать escapeHtmlAttr()вместо
Фабиан Шменглер
источник
1
Хорошая работа Я добавил небольшую заметку к своему ответу, чтобы ссылаться на ваш при использовании 2.1. Интересно, что в Magento U упоминаются только методы, которые я упомянул в своем ответе. Я предполагаю, что курс - только 2.0
Рафаэль в Цифровом
escapeHtmlAttrи escapeHtmlAttrне существует в 2.1.2 ... по крайней мере, в, /vendor/magento/framework/Escaper.phpесли они не добавили его позже и не пометили тегом magento ..
OZZIE
2
Хороший улов, мой ответ на самом деле основывался на последних разработках. Согласно devdocs, другие методы будут устаревшими с 2.2
Фабиан Шменглер
Есть ли метод, который можно использовать для очистки произвольного фрагмента HTML, который может иметь тег img в нем?
Corgalore
Чисто в каком смысле?
Фабиан Шменглер
14

Это для Magento 2.0. Для 2.1 обратитесь к ответу Фабиана

escapeHtml

Используйте эту функцию в случае вывода строки, которая не должна содержать HTML.

Пример:

<span class='label'><?php echo $block->escapeHtml($block->getLabel()); ?></span>

escapeQuote

Используйте эту функцию в случае атрибутов HTML

Пример:

<span class="<?php echo $block->escapeQuote($block->getSpanClass()); ?>">Description</span>

escapeUrl

Используйте эту функцию в случае вывода URL (без предотвращения XSS - только преобразование символов)

Пример:

<a href="<?php echo $block->escapeUrl($block->getUrl()); ?>">Link</a>

escapeXssInUrl

Используйте эту функцию в случае вывода URL-адреса (с предотвращением XSS - в том числе символьного разговора)

Пример:

<a href="<?php echo $block->escapeXssInUrl($block->getUrl()); ?>">Link</a>

Что не нужно убегать?

  • Тип приведения и функция php count()(пример echo (int)$var)
  • Вывод в одинарных кавычках (пример echo 'test')
  • Вывод в двойных кавычках без переменных (пример echo "test")

__метод

Этот используется для целей перевода. Используйте его, когда знаете, что строку можно перевести.

Например:

<caption class="table-caption"><?php /* @escapeNotVerified */ echo __('More Information') ?></caption>
Рафаэль в цифровом пианизме
источник
хорошая работа .. Rapheal
Амит Бера
1
Должны ли мы избежать каждого перевода __()тоже? Я немного устал вставлять /* @escapeNotVerified */везде: /
igloczek
@BartekIgielski см. Мой обновленный ответ. __не в целях безопасности, а в целях перевода
Рафаэль из Digital
1
Также я рекомендую экранировать переведенные строки, напримерecho $this->escapeHtml(__('Text to translate'))
KAndy
2
В настоящее время на странице devdocs есть примечание, что некоторые методы будут устаревшими с 2.2. Обязательно зайдите на страницу безопасности шаблона. devdocs.magento.com/guides/v2.0/frontend-dev-guide/templates/…
Анна