Skip to main content

January 17th, 2024

Diving Into ACF’s Latest Security Release

ACF recently released ACF 6.2.5 which is a security release patching an issue that was disclosed to the ACF team in December by Wordfence. The release changes the behavior of the ACF shortcode right now, but in a future release, the same change will be implemented on the_field and the_sub_field. So what does this mean for you?

Immediate Implications for ACF 6.2.5 Release

If your site uses the ACF shortcode, the output will be escaped by wp_kses. That means if you’re using the shortcode to display a field containing potentially unsafe HTML like a script snippet — maybe a GA4 code or a Hubspot form embed — or an iframe — like a YouTube video or Vimeo video — you may see this content break when updating to ACF 6.2.5.

What If You’re Affected by the ACF Shortcode Breaking Change?

If you trust your WordPress users with a contributer access level and higher, it is possible to add a filter that excludes a specific field you’re displaying with a shortcode from being run through this escaping process. If, for example, the field that holds the HTML is called video_embed, you could add a filter like:

add_filter('acf/shortcode/allow_unsafe_html', function ($allowed, $atts) {
  // replace video_embed with your field name
  if ( $atts['field'] === 'video_embed' ) {
    return true;
  }
  return $allowed;
}, 10, 2);

What this code will do is allow potentially unsafe HTML, like scripts and iframes, in this specific field. Again, you should only take this approach if you trust your users as, understandably, it is a security risk.

Another option you have is to allow the tag being used in these fields specifically. If you’re using something like an iframe in ACF fields, for instance, you can explicitly clear them through the wp_kses_allowed_html filter, which ACF provides an example utilizing it to expressly allow an iframe tag, among others. Just keep in mind that with this route, you are still ultimately clearing a tag that could be used maliciously. You’re making the choice to allow any iframe tag if using this type of filter, for example, so it still comes back to whether you can trust your WordPress users.

What If You Don’t Use ACF Shortcodes?

If you don’t use ACF shortcodes, the ACF team, first of all, recommends you disable them. Second of all, in an upcoming ACF release expected in February (ACF 6.2.7), these same changes will go into effect if you’re using the_field or the_sub_field, as well. So let’s say that you have a field containing something like an iframe video embed again called video_embed, you have a couple options.

You can change the way you call the field from doing something like:

<?php the_field('video_embed'); ?>

to:

<?php echo get_field('video_embed'); ?>

This would get around the escaping happening to the_field. Escaping is ultimately best practice, however, so if you’re using get_field vs. the_field, escaping that output in whatever way makes the most sense for the field is always recommended.

If you are ultimately locked into still using the_field for whatever reason, just like you can do with the previously provided shortcode filter, you can get around the escaping in the_field with a filter like:

add_filter('acf/the_field/allow_unsafe_html', function ($allowed, $atts) {
  // replace video_embed with your field name
  if ( $atts['field'] === 'video_embed' ) {
    return true;
  }
  return $allowed;
}, 10, 2);

Again, this should only be done if you trust your users as it is a security risk. However, in a pinch, you can get by if you need to with that.

Also, you have the same option here to allow potentially unsafe tags like an iframe in ACF fields by explicitly clearing them through the wp_kses_allowed_html filter, which ACF provides an example utilizing it to explicitly allow an iframe tag, among others. As previously noted, though, this route is allowing the tag overall, not distinguishing between whether it’s a “good” vs. “bad” iframe so it still has security implications.

Preparing for ACF 6.2.7

If you see a notice in the backend of your site after updating to ACF 6.2.5 that your site uses the_field or the_sub_field, you should start preparing for the ACF 6.2.7 release when these same changes are going to go into effect there. You can test these changes early by opting into the behavior via a filter:

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

This will enable the escaping behavior on the_field and the_sub_field so you can ensure your sites are ready once ACF 6.2.7 rolls around. As with any code, it’s a good idea to test this locally or on a staging environment and not play with fire by deploying it directly on a client’s production environment without understanding how it will impact the site.

If you do not use the_field or the_sub_field and do your own escaping using something like get_field instead, these changes should not impact you.

I know breaking changes are never ideal but neither would letting a security issue persist so kudos to the ACF team for quick attention to address the issue and providing plenty of information on how it can be handled on any client project! I can’t stress enough how important and insightful the ACF blog posts can be for these releases. Often, information provided on these types of plugin updates is minimal but the ACF team always seems to go the extra mile with additional insight so if you’re not keeping up with their blog, I’d highly recommend you do so!

Get the latest in your inbox