WordPress released version 5.5.2 yesterday, which fixed a reflected XSS vulnerability we reported earlier this year. The root cause of this issue is a bug in the way WordPress determines a user’s current page, and which may cause a few other problems as well.
Are You Affected?
This vulnerability is exploitable on every WordPress site and user account. For the exploit to be successful, the attacker must trick an unsuspecting user into clicking on a malicious link or visiting a booby-trapped website.
The root cause of this issue is a bug in the way the $pagenow global variable has been set-up.
Put shortly, these regexes are trying to determine which file is being loaded. They also mitigate simple spoofing techniques like trying to set $pagenow’s value to “test.php” by visiting /wp-admin/index.php/wp-admin/test.php.
That being said, those regexes also contain a very subtle mistake which has gone unnoticed for quite some time: they are using the special dot character.
In a vanilla regular expression, the dot character matches against basically every character except newlines. Add that to the fact that PHP_SELF can contain decoded user-input coming straight from the URI, and you may see how it could cause some issues.
Getting back to our previous example with what we now know, if you want $pagenow to contain test.php, you can force it by visiting /wp-admin/index.php/%0a/wp-admin/test.php.
With that in mind, let’s see how deep the rabbit hole goes.
$pagenow may be used to initiate the $hook_suffix global variable, which is also used quite a bit in WordPress.