13 Mar 2023

Wordfence Has Been Selling Info on Unfixed Vulnerability in YourChannel to Hackers for a Month

Recently, the WPTavern ran a post that claimed that the WordPress security provider Wordfence had responsibly disclosed a couple of vulnerabilities in plugins. That claim seemed to be based on Wordfence claiming they responsibility disclosed the vulnerabilities in their own post, but further information in that post contradicted that, as they also claimed that before they even notified the developer of the plugin about the vulnerability, they had provided a firewall rule for the vulnerability for their paying customers. That isn’t responsible disclosure, as responsible disclosure involves notifying the developer first and giving them a chance to address the vulnerability, before notifying anyone else.

There isn’t any requirement that a security provider do responsible disclosure, but beyond the big problem of security lying about what they are doing when trust is such an important part of security, Wordfence has criticized others for not doing responsible disclosure.

That wasn’t a one-off issue. In Wordfence’s disclosure policy, they claim to do responsible disclosure and then go on to say they will sell information about the vulnerabilities through firewall rules before even notifying the developer. That policy also obliquely acknowledges that those firewall rules could be misused:

Where possible, we develop a firewall rule to protect our customers. This rule is obfuscated to prevent reverse engineering.

You wouldn’t need to obfuscate the rules to prevent reverse engineering if the rules are harmless.

As we have noted in the past, the obfuscation they do doesn’t actually prevent reverse engineering, which if they really have the security experts on staff that they claim to, they would know.

With another plugin, YourChannel, Wordfence has now been selling information on an undisclosed unfixed vulnerability for a month to any hacker willing to pay. As it is now in their free data, even hackers not paying have access to the information. Their customers have been protected from this, but others have not. So we want to get the word out to others.

(We have been warning our customers about an unrelated only partially fixed vulnerability in the plugin for over a month, which Wordfence and others have labeled as having been fixed. We notified the developer of that issue and offered to help them address it, but we so far haven’t gotten any response.)

Here is Wordfence’s rule for the vulnerability:

if ((lengthGreaterThan('0', request.md5Body['c3949016966fbe59982f505428a2a9f0'], request.md5QueryString['c3949016966fbe59982f505428a2a9f0'], request.md5Body['eb469e806d377d9694172da4ad9219c1'], request.md5QueryString['eb469e806d377d9694172da4ad9219c1']) or identical('', request.md5QueryString['c3949016966fbe59982f505428a2a9f0'], request.md5QueryString['eb469e806d377d9694172da4ad9219c1'], request.md5Body['c3949016966fbe59982f505428a2a9f0'], request.md5Body['eb469e806d377d9694172da4ad9219c1'])) and currentUserIsNot('administrator', server.empty)):
	block(id=543, category='bypass', score=100, description='WAF-RULE-543', whitelist=0)

It is obfuscated, but it doesn’t prevent reverse engineering. Here is the rule without the obfuscation, which an automated system we have was able to instantly generate (so a hacker could certainly do the same thing):

if ((lengthGreaterThan('0', request.md5Body['DECODEDyrc_nuke'], request.md5QueryString['DECODEDyrc_nuke'], request.md5Body['DECODEDyrc_clear_cache'], request.md5QueryString['DECODEDyrc_clear_cache']) or identical('', request.md5QueryString['DECODEDyrc_nuke'], request.md5QueryString['DECODEDyrc_clear_cache'], request.md5Body['DECODEDyrc_nuke'], request.md5Body['DECODEDyrc_clear_cache'])) and currentUserIsNot('administrator', server.empty)):
	block(id=543, category='bypass', score=100, description='WAF-RULE-543', whitelist=0)

The automated tool also instantly identified that rule as relating to the plugin YourChannel.

A search of the plugin shows that the obfuscated content relates to the following code in the file /YourChannel.php:

968
969
970
971
972
973
974
975
976
if( isset($_GET['yrc_clear_cache']) ){
	clearYRCCache();
}
 
if( is_admin() && isset($_GET['yrc_nuke']) ){
	delete_option('yrc_keys'); 
	delete_option('yrc_playlist_keys');
	clearYRCCache();
}

The first part of that will clear a cache, if certain input is in a URL. The second part will delete a couple of settings and clear a cache, if certain input is in a URL. The usage of the function is_admin() in the second just checks if an admin page is being accessed. Possibly, the developer was thinking it would check if a user with the Administrator role was making the request.

The practical implication of that code is that even those not logged in to WordPress can reset the plugin’s settings.

Leave a Reply

Your email address will not be published.