Web production note

 【更新日 :

【WordPress】ACF 6.2.7以降でthe_field()やthe_sub_field()がHTMLエスケープされる仕様変更への対応方法

記事執筆次点ではACF 6.2.5です。
※本記事は以下のACF 6.2.5 セキュリティリリース記事を元に執筆しているため、今後のアップデート状況によっては適宜加筆修正する可能性があります。

ACF 6.2.7以降 the_field() と the_sub_field() で出力する場合にWordPressのHTMLエスケープ関数 wp_kses() を経由するようになる

ACF 6.2.5では、ショートコード [ acf field="field_name"] に対してWordPressのHTMLエスケープ関数wp_kses()がデフォルトで働くようになりましたが、2024年2月以降に予定されているACF 6.2.7以降には、the_field() と the_sub_field()にもHTMLエスケープ処理がデフォルトで働くようになるそうです。

単純に文字を出力するような想定であれば特に問題ないはずですが、カスタムフィールド内にHTMLタグを登録する想定で実装している場合は、styleタグやscriptタグなどが出力されなくなるはずなので対策が必要です。

From ACF 6.2.5, use of the ACF Shortcode to output an ACF field will be escaped by the WordPress HTML escaping function wp_kses.

This has potential to be a breaking change if you’re using the shortcode ([ acf field=”field_name”]) to output potentially unsafe HTML such as scripts or iframes for textarea or WYSIWYG fields.

〜中略〜

From ACF 6.2.7, expected in February 2024, escaping unsafe HTML will also apply to other functions where ACF handles outputting the value of a field, namely the the_field() and the_sub_field() functions. To help get ahead of the impact of this future change, we’ve also added a notice in ACF 6.2.5 alerting you that your site is outputting HTML that will be altered by the escaping coming in 6.2.7.

https://www.advancedcustomfields.com/blog/acf-6-2-5-security-release/

HTMLが削除された場合はWordPressの管理画面にエラーメッセージが表示される

ACF 6.2.5 からはショートコードで出力された値から安全でない HTML が削除された場合はエラーメッセージを出すようになりました。エラーを検出するたびに、ACF は影響を受けた関数呼び出しに関するデータをログに記録するそうです。

メッセージを完全無効化できるショートコードも用意されました。

add_filter( 'acf/admin/prevent_escaped_html_notice', '__return_true' );

Whenever we detect that escaping the field value has modified the output value, ACF will log data about the affected function call.

Any detected modification will trigger the log, but it may not necessarily be a breaking change. For example, & become & when escaped. This would be detected as a modification, but is unlikely to be a problem as it will still be rendered normally in the browser. In these cases you do not need to make any code changes, instead you can leave the upcoming automatic escaping to work correctly.

This log is stored as an option in the wp_options table. Whenever this log contains entries, the notices in WordPress admin will be shown for all users with the “Editor” role and higher by default. Users with the ability to manage ACF will have the option to view the full details. Users without the ability to manage ACF will be asked to contact their site admin about the error.

Admin users have the ability to dismiss the message, which will also clear the log. Dismissing the notice after you’ve made fixes will allow you to verify you’ve fixed every instance, as the message will not return after the affected pages have been loaded.

https://www.advancedcustomfields.com/blog/acf-6-2-5-security-release/#detection-and-notice-information

以前の仕様のまま値を出力するには、echo get_field()を利用する

HTMLエスケープさせたくない値に関しては、the_field()を利用せず echo get_field() で値を出力するとエスケープなしで返り値をそのまま出力することができます。

<?php 
  //ACF 6.2.7以降 the_field()はHTMLエスケープされる
  the_field('field_name');

  //HTMLエスケープなしで値をそのまま出力
  echo get_field('field_name');
?>

if you’re confident you can trust every user registered on your site with contributor or higher access—we recommend you use echo get_field() to output this unsafe HTML to ensure it’s not filtered.

https://www.advancedcustomfields.com/blog/acf-6-2-5-security-release/#how-to-use-acf-securely

apply_filters()でHTMLエスケープを条件付きで無効にする

functions.phpでコントロールしたい場合、以下のフィルターが追加されています。

  • acf/shortcode/allow_unsafe_htmlショートコードのエスケープを無効
  • acf/the_field/allow_unsafe_htmlthe_field()のエスケープを無効

ショートコードのエスケープを無効

apply_filters( 'acf/shortcode/allow_unsafe_html', false, $attributes, $field_type, $field_object );

//利用例
//iframeを出力するために[acf field="podcast_iframe"]を使っている場合
add_filter( 'acf/shortcode/allow_unsafe_html', function ( $allowed, $atts ) {
  if ( $atts['field'] === 'podcast_iframe' ) {
    return true;
  }
  return $allowed;
}, 10, 2 );

the_field()のエスケープを無効

apply_filters( 'acf/the_field/allow_unsafe_html', false, $selector, $post_id, $field_type, $field_object );

//利用例
//google_maps_iframeというフィールドがあり、そこにグーグルマップのiframeが含まれている場合
add_filter( 'acf/the_field/allow_unsafe_html', function( $allowed, $selector ) {
  if ( $selector === "google_maps_iframe" ) {
      return true;
  }
  return $allowed;
}, 10, 2);

フィルターを使ってACF 6.2.5からHTMLエスケープを早期に有効化する

動作検証など今から実施したい場合は、以下のフィルターをfunctions.phpに追加することでthe_field() と the_sub_field() のHTMLエスケープ処理を有効化できます

add_filter( 'acf/the_field/escape_html_optin', '__return_true' );

参考リンク

目次 を閉じる