Предисловие
В версии ACF 5.10 была представлена важная функция безопасности — экранирование HTML. Впервые она была представлена в качестве экспериментальной функции в ACF 5.9.6 и обеспечивает прохождение всего HTML-контента, отображаемого ACF, через функцию WordPress wp_kses()
.
Запуская весь HTML-контент через эту нативную функцию WordPress, ACF гарантирует, что любой HTML, который он отображает, не подвержен атакам межсайтового скриптинга (XSS).
Важно отметить, что экранирование будет работать только для HTML-контента, отображаемого плагином АЦФ в панели управления WordPress или на любых формах для конечных пользователей, отображаемых через acf_form()
. И не будет работать для значений полей, загруженные через функции API, такие как get_field()
и the_field()
. Мы не делаем никаких предположений о том, где вы используете значения полей в своей теме и не производим экранирование для них.
Реализация
Система экранирования HTML в ACF представляет новую функцию экранирования acf_esc_html()
, которая теперь используется во всем плагине ACF для отображения HTML. Эта функция принимает содержимое для рендера и передает его в функцию wp_kses()
, возвращая результат. Она также передает контекста acf
.
/**
* Очищает текстовое содержимое и удаляет недопустимый HTML.
*
* Эта функция имитирует wp_kses_post() с контекстом "acf" для расширяемости.
*
* @date 16/4/21
* @since 5.9.6
*
* @param string $string
* @return string
*/
function acf_esc_html( $string = '' ) {
return wp_kses( (string) $string, 'acf' );
}
Содержимое ACF, прошедшее через wp_kses()
, просит WordPress удалить любые недопустимые HTML-теги или атрибуты тегов. Список разрешенных тегов управляется функцией WordPress wp_kses_allowed_html()
. По-умолчанию WordPress поставляется с рядом предопределенных разрешенных тегов и их разрешенных атрибутов. Вот пример разрешенного тега button и его разрешенных атрибутов.
[button] => Array
(
[disabled] => true
[name] => true
[type] => true
[value] => true
[aria-describedby] => true
[aria-details] => true
[aria-label] => true
[aria-labelledby] => true
[aria-hidden] => true
[class] => true
[id] => true
[style] => true
[title] => true
[role] => true
[data-*] => true
)
Если HTML-элемент в содержимом, переданном в wp_kses()
, не находится в списке разрешенных тегов, или атрибут тега отсутствует в списке разрешенных, он будет удален из содержимого.
Кастомизация
Передача пользовательского контекста acf
в wp_kses()
позволяет настраивать разрешенные теги HTML и атрибуты. Если у вас есть конкретный HTML-тег или атрибут тега, который вы хотите разрешить, вы можете добавить его в список разрешенных тегов, используя фильтр-хук wp_kses_allowed_html
в PHP.
Например, вы можете использовать этот фильтр в functions.php вашей темы или плагине, чтобы разрешить тег iframe
:
add_filter( 'wp_kses_allowed_html', 'acf_add_allowed_iframe_tag', 10, 2 );
function acf_add_allowed_iframe_tag( $tags, $context ) {
if ( $context === 'acf' ) {
$tags['iframe'] = array(
'src' => true,
'height' => true,
'width' => true,
'frameborder' => true,
'allowfullscreen' => true,
);
}
return $tags;
}
Вот еще один пример, который разрешает явно указанные теги svg
и path
:
add_filter( 'wp_kses_allowed_html', 'acf_add_allowed_svg_tag', 10, 2 );
function acf_add_allowed_svg_tag( $tags, $context ) {
if ( $context === 'acf' ) {
$tags['svg'] = array(
'xmlns' => true,
'fill' => true,
'viewbox' => true,
'role' => true,
'aria-hidden' => true,
'focusable' => true,
);
$tags['path'] = array(
'd' => true,
'fill' => true,
);
}
return $tags;
}
Важно помнить, что любые разрешенные теги могут иметь последствия для безопасности, поэтому следует разрешать только теги, которые считаются безопасными. Примером потенциально небезопасного тега может быть тег script
.
В WordPress, по-умолчанию, встроено экранирование, которое удаляет теги и атрибуты тегов HTML, которые считает небезопасными, также удаляются свойства CSS, которые считаются небезопасными, например, свойство display. В некоторых случаях вам может потребоваться определить и добавить встроенный стиль в панель управления WordPress. Например, такое.
<div style="display: flex">
Поскольку свойство display удаляется, это свойство также будет удалено из тега div.
Как и в случае с разрешенными HTML-тегами, вы также можете разрешить определенные свойства CSS, используя фильтр safe_style_css
:
add_filter( 'safe_style_css', 'add_display_to_safe_css', 10, 1 );
function add_display_to_safe_css( $css_attributes ) {
$css_attributes[] = 'display';
return $css_attributes;
}
Пожалуйста, имейте в виду, что хотя это возможно, мы не рекомендуем делать это, тк это может создать уязвимости безопасности на вашем сайте.
Экранирование HTML в ACF
В Advanced Custom Fields PRO версии 5.12 и выше, WordPress будет применять свою стандартную санитизацию wp_kses_post()
к блокам ACF для пользователей без разрешения unfiltered_html
. В некоторых случаях это может привести к удалению HTML-кода из содержимого блока, и следовательно, этот контент не будет отображаться на frontend, что не происходило в версиях до 5.12.
Если у пользователя нет возможности unfiltered_html
, но ему нужно вставлять HTML в блоки ACF, который удаляется функцией wp_kses_post()
, вы можете добавить поддержку определенных HTML-тегов, используя тот же фильтр-хук wp_kses_allowed_html
, что и ранее, но с контекстом «post»:
add_filter( 'wp_kses_allowed_html', 'acf_add_allowed_iframe_tag', 10, 2 );
function acf_add_allowed_iframe_tag( $tags, $context ) {
if ( $context === 'post' ) {
$tags['iframe'] = array(
'src' => true,
'height' => true,
'width' => true,
'frameborder' => true,
'allowfullscreen' => true,
);
}
return $tags;
}
Кроме того, вы можете вручную предоставить пользователю разрешение unfiltered_html
.