Reflected XSS in Advanced Custom Fields Plugins Affecting 2+ Million Sites

Published 5 May 2023
Updated 13 December 2024
Table of Contents

This blog post is about the Advanced Custom Fields free and pro plugin vulnerability. If you’re an Advanced Custom Fields free and pro user, please update the plugin to at least version 6.1.6. The security fix also backported on version 5.12.6.

Patchstack Developer and Enterprise Plan users are protected from the vulnerability.

You can also sign up for the Patchstack Community plan to be notified about vulnerabilities as soon as they become disclosed.

For plugin developers, we have security audit services and Threat Intelligence Feed API for hosting companies.

Update regarding exploitation attempts

As we are writing this update on 16 May 2023, we notice claims circulating in the media that the sample PoC URL on this article is being used to mass-exploit websites. We found that to be unlikely since the XSS could only be triggered by logged-in users (mainly administrators) that have access to the Advanced Custom Fields feature. We assume that the attacker tries to directly hit the sample PoC URL and it doesn’t indicates that the attempt is a concrete exploitation. This case mostly applies across vulnerabilities that require user interaction such as CSRF and Reflected XSS. Until this update is published, our monitoring system didn’t catch any concrete exploitation attempts on our customers.

About the Advanced Custom Fields WordPress plugin

The plugin Advanced Custom Fields and Advanced Custom Fields Pro (versions 6.1.5 and below, free and pro version), has over 2 million active installations. It is known as the most popular custom fields plugins in WordPress.

Advanced Custom Fields WordPress vulnerability

This plugin is a WordPress plugin that allows us to add extra content fields to our WordPress edit screens. These extra content fields are more commonly referred to as Custom Fields and can allow us to build websites faster with more available fields.

The security vulnerability in Advanced Custom Fields

This plugin suffers from reflected XSS vulnerability.

This vulnerability allows any unauthenticated user from stealing sensitive information to, in this case, privilege escalation on the WordPress site by tricking privileged users to visit the crafted URL path.

The described vulnerability was fixed in version 6.1.6, also fixed in version 5.12.6, and assigned CVE-2023-30777.

Find out more from the Patchstack database and here.

The underlying vulnerability is located on admin_body_class function handler:

public function admin_body_class( $classes ) {
    $classes .= " acf-admin-page acf-internal-post-type {$this->admin_body_class}";

    if ( $this->view ) {
        $classes .= " view-{$this->view}";
    }

    return $classes;
}

The admin_body_class configured to be an extra handler of WordPress own hook that is also named admin_body_class. This hook controls and filters the CSS classes for the main body tag in the admin area.

// Add hooks.
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );

If we look deeper at the implementation of the admin_body_class on WordPress core, we could see that the outputted value of the hook is not properly sanitized and directly constructed on the HTML page :

$admin_body_classes = apply_filters( 'admin_body_class', '' );
$admin_body_classes = ltrim( $admin_body_classes . ' ' . $admin_body_class );
?>
<body class="wp-admin wp-core-ui no-js <?php echo $admin_body_classes; ?>">
<script type="text/javascript">
	document.body.className = document.body.className.replace('no-js','js');
</script>

Because of that condition, there is a potential XSS vulnerability if the admin_body_class hook function handler doesn’t properly sanitized the returned classes string.

Let’s get back to the hook function handler, the code will directly concatenated $this->view variable to the $classes variable that will be returned as classes string. We actually could fully control the $this->view variable from current_screen function :

public function current_screen() {
    // Bail early if not the list admin page.
    if ( ! acf_is_screen( "edit-{$this->post_type}" ) ) {
        return;
    }

    // Get the current view.
    $this->view = isset( $_GET['post_status'] ) ? sanitize_text_field( $_GET['post_status'] ) : ''; //
-------------------------------------

Sanitization using sanitize_text_field function is not enough to prevent XSS, since we could still use a DOM XSS payload. Combining all of that, the XSS could be achieved using this example payload :

http://<WORDPRESS_SITE>/wp-admin/edit.php?post_type=acf-field-group&post_status=xxxxxxx" onload=alert(document.domain) xxx="

The reflected HTML structure that is being shown on the front-end could be something like this :

<body class="wp-admin wp-core-ui no-js acf-admin-5-3 acf-browser-chrome acf-admin-page acf-internal-post-type acf-admin-field-groups view-xxxxxxx\" onload=alert(document.domain) xxx=\" edit-php auto-fold admin-bar post-type-acf-field-group branch-6-2 version-6-2 admin-color-fresh locale-en-us no-customize-support no-svg">

Note that this vulnerability could be triggered on a default installation or configuration of the Advanced Custom Fields plugin. The XSS also could only be triggered by logged-in users that have access to the Advanced Custom Fields plugin.

The patch in Advanced Custom Fields

Since this issue is mainly because the code directly constructed a variable to the HTML without proper sanitization, implementing esc_attr function should be enough to patch the issue. The patch can be found below :

Advanced Custom Fields

There are many WordPress hook functions that are used across plugin and theme codes. One of them is admin_body_class hook. Make sure to sanitize the classes string that outputted when using the hook using sanitize function like esc_attr.

Timeline

02 May 2023We found the vulnerability and reached out to the plugin vendor.
04 May 2023Advanced Custom Fields free and pro plugin version 5.12.6 and 6.1.6 was published to patch the reported issues.
05 May 2023Added the vulnerabilities to the Patchstack vulnerability database.
05 May 2023Published the article.

Help us make the Internet a safer place

Making the WordPress ecosystem more secure is a team effort, and we believe that plugin developers and security researchers should work together.

  • If you’re a plugin developer, join our mVDP program that makes it easier to report, manage and address vulnerabilities in your software.
  • If you’re a security researcher, join Patchstack Alliance to report vulnerabilities & earn rewards.

The latest in Security advisories

Looks like your browser is blocking our support chat widget. Turn off adblockers and reload the page.
crossmenu