Autoptimize closing in on W3 Total Cache

Fun fact; As per wordpress.org “popular plugins” ranking , Autoptimize is slowly but surely closing in on what used to be the go-to solution for Web Performance Optimization W3 Total Cache based on the “active installs” metric. Who would have thought? What a crazy ride …

Warning: bug in W3 Total Cache impacts Autoptimize

Update 4th Feb: the HTML minify bug was fixed in W3TC v. 0.9.7.2, released a couple of days ago.
Update 19th Feb: I’m still seeing issues caused by W3TC, seems like not all is fixed fully yet.


Quick heads-up for users that have both W3 Total Cache and Autoptimize installed; the latest W3TC update (version 0.9.7.1) introduces a nasty bug in the HTML minifier which also impacts Autoptimize as that uses the same minifier class (Minify_HTML, part of Mr. Clay’s Minify). When W3TC is running the Minify_HTML class is loaded by and from W3TC, meaning AO’s autoload does not have to load the Minify_HTML from AO proper (which does not have that problem).
The bug sees some characters, esp. quotes disappear from the HTML leading to all sorts of .. weirdness from Pinterest icons not showing over mis-aligned titles in RevSlider to broken custom share buttons and more.
If you’re impacted by the bug, you can do one of the following;

  • disable HTML optimization in Autoptimize (and W3TC)
  • OR temporarily disable W3TC (or switch to another page cache plugins)
  • OR download and install the previous version of W3TC (0.9.7)

Fingers crossed they’ll release an update soon!

WP Caching plugin vulnerability debrief

Now that both WP Super Cache and W3 Total Cache developers have released a new version of their respective plugins (upgrade first, continue reading after) it seems time for a small “post mortem“.
The problem was in the interpretation of dynamic snippets, that are contained inside a number of specific HTML-comment tags. These snippets allow both plugins (and their predecessor WP Cache) to cache pages while keeping a limited amount of dynamic, PHP-generated content in them that can be executed on the fly. Think ESI in e.g. Varnish.
The vulnerability, which was originally discovered by kisscsaby and reported 3 weeks ago on the wordpress.org plugins support forum, had multiple causes:

  1. Unlike ESI’s, dynamic snippets can not only be includes (mclude) but also PHP-code (mfunc). Whereas one could consider includes of known files more or less safe, inclusion of PHP-code introduces a risk.
  2. As WP Super Cache & W3 Total Cache keep entire pages in cache and as pages can contain comments, that user generated content is parsed for dynamic snippets as well.
  3. WordPress core by default only allows a limited set of HTML in comments (“a blockquote code em strong ul ol li”), but it also leaves HTML comments in place.

As a result, blogs with WP Super Cache (before version 1.3) and W3 Total Cache (before version 0.9.2.9) were at risk of PHP code injection. Blog comments could contain dynamic snippets (in HTML-comments) and WordPress core did not them filter out. Upon a such a malicious comment having been submitted, a new cached version of the page was created that included the injected PHP-code. Upon the first request of the cached page, that code was successfully executed.
I stumbled on the vulnerability report about a week and a half ago, while researching why dynamic snippets weren’t executing when Autoptimize was active (simple really, Autoptimize by default removes HTML comments, the upcoming 1.6.3 will leave mfunc/mclude in place). As this seemed like a pretty severe security hole and as there was no feedback from developers in the support thread, I created a small “stopgap plugin” to mitigate the threat on April 10th, mailed security@wordpress.org and plugins@wordpress.org and requested WP Safer Cache being published on wordpress.org on the 11th. A couple of hours later WP Super Cache’s Donncha O Caoimh contacted me and the same day he released a version (1.3) that fixed this vulnerability by parsing out potential exploits from comments as they are posted and as they are rendered. On April 12th W3 Total Cache’s Frederick Townes confirmed they were working on a fix. Version 0.9.2.9 got released on April 17th, disabling dynamic snippets by default and when these are enabled, they require a secret alphanumeric key to be included in the snippet which is checked against one that is defined in wp-config.php.
Conclusions; The fact that this didn’t generate any fuss (as opposed to W3 Total Cache’s widely published information disclosure vulnerability in December 2012) is surprising. PHP Code injection clearly is a more severe security risk that must have been there for a long time already. The fact that this only got discovered recently is baffling. And why WordPress core doesn’t filter out HTML-comments from submitted blog comments, others seem to understand, but to me that remains the biggest mystery of all.

WP Safer Cache: stopgap for WordPress Cache plugins vulnerability

[UPDATE April 18th 2013: this vulnerability has been fixed in both WP Super Cache and W3 Total Cache. You can find more information in this “post mortem” blogpost]
[UPDATE April 11th to reflect that WP Super Cache version 1.3 fixed this issue]
There was a pretty severe vulnerability in WordPress installations that had WP Super Cache (until version 1.2, 1.3 fixed this issue) or W3 Total Cache (up until version 0.9.2.8) plugins activated. This security bug would, under certain circumstances, allow attackers to inject and execute arbitrary PHP code in comments.
The vulnerability could have been handled in WordPress core or in WP Super Cache and W3 Total Cache separately (with my preference being a fix in  comment sanitization in core). On April 11th WP Super Cache version 1.3 was released, fixing this issue and W3 Total Cache released a fix on April 18th. If you are on an older version of WP Super Cache or W3 Total Cache (do upgrade!), you might be interested in installing this little plugin that cleans out malicious … stuff from comments being posted.
As always; comments, bugs & improvements are welcome in the comment-field below or via the contact form.