16 января 2024 года вышел ACF 6.2.5, релиз с исправлением безопасности. С этой версии шорткод прогоняет значение поля через функцию WordPress wp_kses: безопасный HTML остаётся, а скрипты, iframe и подобное вырезаются. Закрыли дыру, найденную Francesco Carlucci и командой Wordfence: автор с ролью contributor и выше, у которого нет права unfiltered_html, мог записать вредоносный HTML в произвольное поле записи в обход ACF и вывести его на сайт шорткодом.
С тех пор ACF ужесточал правила ещё несколько раз, поэтому ниже и про 6.2.5, и про то, как всё устроено сейчас, в версии 6.8.
Что ломается на практике
Раньше шорткод отдавал поле как есть. С 6.2.5 значение проходит через kses: картинки, ссылки, таблицы и форматирование остаются, а <script> и <iframe> по умолчанию исчезают. Если через шорткод выводилось поле с кодом подкаста, карты или виджета, после обновления на сайте будет пусто. Чтобы было понятно, что чинить, ACF показывает в админке уведомление со списком затронутых полей.
Какие теги и атрибуты разрешены, задаёт kses.php в ядре WordPress. iframe и script в этот список по умолчанию не входят.
the_field() и the_sub_field() с версии 6.2.7
В 6.2.5 ACF только предупреждал, что вывод the_field() и the_sub_field() изменится. В ACF 6.2.7 от 27 февраля 2024 года экранирование включили и для них: HTML не запрещён целиком, остаётся безопасный набор kses. Там же появился фильтр acf/shortcode/prevent_access, которым можно закрыть шорткоду доступ, например, к полям страниц настроек, пользователей или приватных записей.
Функция get_field() возвращает значение как есть, без экранирования. Если выводите его через echo, экранировать нужно самому.
ACF 6.3: шорткод выключен по умолчанию
Дальше ACF пошёл ещё строже. Как написано в документации шорткода, с ACF 6.3.0 шорткод на новых установках выключен по умолчанию: он даёт доступ к любому полю любой записи, и каждый, кто может публиковать, увидит данные, если знает имя поля. На сайтах, которые обновились со старых версий, шорткод продолжает работать. Если он нужен на новом сайте, например для конструктора страниц, его включают так:
add_action( 'acf/init', function () {
acf_update_setting( 'enable_shortcode', true );
} );
В ACF 6.3.6 от 28 августа 2024 года добавили ещё одну настройку поля на вкладке «Представление»: Allow Access to Value in Editor UI. Она разрешает доступ к значению поля из редактора через шорткод или Block Bindings. У полей, созданных до 6.3.6, она включена, а у всех новых выключена, так что для нового поля доступ нужно включить явно.
Как точечно разрешить небезопасный HTML
Если вы доверяете авторам или HTML в поля кладёте только сами, есть два фильтра. Лучше ограничивать их именем или ключом поля, а не возвращать true для всего сайта:
acf/shortcode/allow_unsafe_htmlдля шорткода, аргументы: решение, атрибуты шорткода, тип поля, объект поля;acf/the_field/allow_unsafe_htmlдляthe_field()иthe_sub_field(), аргументы: решение, селектор, ID записи, тип поля, объект поля.
Пример: поле podcast_iframe через шорткод должно отдавать iframe:
add_filter( 'acf/shortcode/allow_unsafe_html', function ( $allowed, $atts ) {
if ( isset( $atts['field'] ) && 'podcast_iframe' === $atts['field'] ) {
return true;
}
return $allowed;
}, 10, 2 );
Пример для поля с картой Google через the_field():
add_filter( 'acf/the_field/allow_unsafe_html', function ( $allowed, $selector ) {
if ( 'google_maps_iframe' === $selector ) {
return true;
}
return $allowed;
}, 10, 2 );
Что сделать на своём сайте
- Обновить ACF. Текущая версия в каталоге wordpress.org 6.8.10, она требует WordPress 6.2 и PHP 7.4 или новее.
- Зайти в админку и посмотреть уведомления ACF о полях, вывод которых изменился.
- Пройтись по страницам, где через шорткод или the_field() выводятся embed-коды.
- Для нужных полей добавить фильтры allow_unsafe_html, остальное оставить под kses.
- Если шорткод не нужен, выключить его настройкой enable_shortcode со значением false.
- По возможности вынести embed-коды в отдельные поля и не давать редактировать HTML тем, кто не администратор.
В итоге с ACF 6.2.5 шорткод, а с 6.2.7 и the_field() режут небезопасный HTML, а с 6.3 шорткод на новых сайтах вообще выключен. Embed-коды в полях по-прежнему можно выводить, но только через фильтры allow_unsafe_html для конкретных полей, а не отключая защиту для всего сайта.