4 May 2023

Reflected Cross-Site Scripting (XSS) Vulnerability in Advanced Custom Fields

To better detect vulnerabilities being fixed in WordPress plugins in the WordPress Plugin Directory, we run all the changes being made to plugins used by our customers and plugins with at least a million installs through a machine learning (artificial intelligence) based system we created. Today, that flagged a change being made to a 2+ million install plugin Advanced Custom Fields as fixing a vulnerability. The changelog of the plugin suggested that might be correct, as the changelog associated with that change says that it “resolves an XSS vulnerability in ACF’s admin pages”, which was credited to Rafie Muhammad

You can’t rely on changelog to provide accurate information, as the developer of this plugin, WP Engine, didn’t disclose it was fixing a vulnerability in another of their plugins recently, and even if the changelog makes the claim, it doesn’t mean that a vulnerability really existed or it has been fixed. As we have found with other changes being flagged by this monitoring system, WordPress plugin developer sometimes fail to disclose they are fixing a vulnerability and also fail to actually fix it.

Looking at the changes made in the version flagged by our system, we found that in two files, escaping was added when variables were output. In a third file, sanitization of user input was being changed and escaping was being added when it was output. A bit of testing confirmed that the changed code in that file previously permitted reflected cross-site scripting (XSS) to occur. By default, it could only be exploited against users logged in to WordPress with the Administrator role.

That occurred as user input, in the form of the GET input “post_status”, was sanitized using sanitize_text_field():

120
$this->view = isset( $_GET['post_status'] ) ? sanitize_text_field( $_GET['post_status'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

That doesn’t make it safe for outputting in an HTML attribute, which is what happened in other code that was changed:

228
$classes .= " view-{$this->view}";

In the new version, usage of esc_attr() to properly escape that was added to that code to address that:

228
$classes .= ' view-' . esc_attr( $this->view );

We looked over the rest of the plugin’s code for any similar issues still in it and didn’t find any.

Proof of Concept

The following proof of concept will cause an alert box with the message /XSS/. to be shown, when logged in to WordPress as an Administrator. In Safari and other web browsers that provide XSS filtering this proof of concept will not work.

Replace “[path to WordPress]” with the location of WordPress.

http://[path to WordPress]/wp-admin/edit.php?post_type=acf-field-group&post_status="+style=animation-name:rotation+onanimationstart=alert(/XSS/)//

Plugin Security Scorecard Grade for Advanced Custom Fields

Checked on March 19, 2025
C+

See issues causing the plugin to get less than A+ grade

Leave a Reply

Your email address will not be published. Required fields are marked *