ACF version5.11.1にセキュリティアップデートが含まれる
ACFのversion5.11.1がリリースされました。その中にはセキュリティアップデートがありました。
修正対象の脆弱性の内容としては、
the_field
やget_field
ではACFでフィールド定義したフィールド以外の項目も取得できてしまうのでACFのショートコードでフィールド定義されていない項目が取得できてしまうというということでした。
これはショートコードを記載可能なユーザーであればACFのショートコードを使用することで
postmeta
やusermeta
のmeta_value
が取得できてしまうので構築されているシステムによってはクリティカルな情報が出力されてしまうことが懸念されます。
その対処として、ショートコードではACFで定義されていない項目は取得できないようになりました。
この対処を行うための実装を確認し、影響範囲を考えていきたいと思います。
ACFの実装内容を確認
get_field
の処理内で実行されるacf_get_value
という関数があります。この関数内でセキュリティアップデートによる対応が行われていました。
以下がセキュリティアップデートによる追加されたコードです。
// If we still don't have a proper field array, the field doesn't exist currently.
if ( empty( $field['type'] ) && empty( $field['key'] ) ) {
// Get field ID & type.
$decoded = acf_decode_post_id( $post_id );
if ( apply_filters( 'acf/prevent_access_to_unknown_fields', false ) || ( 'option' === $decoded['type'] && 'options' !== $decoded['id'] ) ) {
return null;
}
do_action( 'acf/get_invalid_field_value', $field, __FUNCTION__ );
}
$field
内に値が存在するかどうか確認し、存在しない場合はACFのフィールド定義が行われていないという扱いになります。その後、filter
acf/prevent_access_to_unknown_fields
にて最終的に取得できる値がtrue
の時データベースに値は取得せず、
null
が返却されます。この部分のコードでは
apply_filters
の第2引数はfalse
のため、null
は返さずそのまま処理を続けるように思います。ではここでACFのショートコード側のロジックを見てみます。
function acf_shortcode( $atts ) {
・・・省略
$access_already_prevented = apply_filters( 'acf/prevent_access_to_unknown_fields', false );
$filter_applied = false;
if ( ! $access_already_prevented ) {
$filter_applied = true;
add_filter( 'acf/prevent_access_to_unknown_fields', '__return_true' );
}
・・・省略
}
add_shortcode( 'acf', 'acf_shortcode' );
acf/prevent_access_to_unknown_fields
に引っ掛けて必ずtrue
が返却されるようになっていました。そのため、ショートコードからACFを使用して値を取得する際にはフィールド定義されているデータしか取得できないことがわかります。
逆に、オリジナルのthemeやplugin内で
get_field
を直接記載して値を取得する場合には今まで通り、フィールド定義されていない項目でも取得できました。
ただし、ACFの公式の見解では非推奨の使い方であり、フィールド定義されていない項目については
get_post_meta
等のWordPressが提供している関数を使用して取得することが推奨されています。そのため、action
acf/get_invalid_field_value
の先で_doing_it_wrongが実行されているのでWP_DEBUG
がtrue
の時はエラーメッセージが表示されちゃいます。影響まとめ
もしACFのショートコードでフィールド定義されていない項目を表示していた場合、表示されなくなります。これは冒頭に記載した通り、セキュリティ的に納得する修正だと思いました。
個人的にはフィールド定義されていない項目を作成したplugin内で
get_field
で取得する実装をした記憶が薄っすらと有りアップデートの影響で該当箇所が動かなかったらどうしようかと思っていたのですが、一先ず動くのようなので良かったです。(ただし
_doing_it_wrong
が実行されるため、WP_DEBUG
を要確認)ただし、あくまで非推奨な使い方であるので見つけ次第修正は進めていこうと思います。