Yesterday I noticed my autoptimized JS-files were returning an internal server error (CSS worked as that is inlined). My Apache error-log had this entry:
[Tue Oct 13 17:23:42 2015] [alert] [client 178.xx.xx.xx] /var/public_html/blog.futtta.be/wp-content/cache/.htaccess: Option Indexes not allowed here
/var/public_html/blog.futtta.be/wp-content/cache/.htaccess is created by WP Super Cache, which got updated recently, a.o. to disable indexes being created of directories, and the .htaccess indeed read;
# BEGIN INDEX
# END INDEX
The solution? I could have edited WPSC’s .htaccess, but my changes could get overwritten there whenever Donncha would feel like it, so in the end I edited my site’s config in Apache;
And all is well now.
The notification might be less welcome for some users; YUI compression and the CDN options are marked as deprecated in this release. YUI compression was pretty exotic and required the installation of JAVA and the YUI compression jar, so I doubt anyone was actually using this. CDN options are deprecated as well; some people reported issue that I could not reproduce or fix. As I consider CDN not to be core functionality and as it can better be accomplished using e.g. WP Super Cache (which is a must-have companion of Autoptimize anyhow), CDN will indeed also be removed from Autoptimize. Expect the deprecated parts to be removed in 1.7.0 (which isn’t planned yet).
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:
- 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.
- 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.
- 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 email@example.com and firstname.lastname@example.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.
[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.
It was time to put my money where my mouth is, or at least to give the use of a CDN a try. Based on previous tests MaxCDN seemed like a decent, dirt-cheap solution, so that’s what the js, css & images for this blog are served from now.
Setting this up was very easy:
- log into MaxCDN and set up a pull zone on static-cdn.blog.futtta.be with origin blog.futtta.be
- create static-cdn.blog.futtta.be in the web interface of my DNS-provider (as a CNAME to the domain-name provided)
- configure WP Super Cache to use static-cdn.blog.futtta.be instead of the non-cdn static.blog.futtta.be)
The speed difference can be huge, especially when routing to my origin VPS-server in Germany isn’t great. I’m sure my 2 overseas users and Google will approve!
Bandwidth-wise, with 10MB/day, I seem to be far from the 1TB/year I’m allowed, so if you’d like me to setup a (temporary) pull zone for your blog so you can check out if this would work for you then just drop me a line.
Some random WordPress-related thingies I’ve been looking into;
Google likes fast! Visitors like fast! So why don’t you go make your site really fast?
Suppose you just bought yourself hosting and you just installed WordPress for blogging or lightweight-CMS-purposes, how can you improve your site’s performance in that case? Easy!
- speed up PHP: use a caching optimizer (I use APC) to significantly speed up PHP performance (don’t bother signing up for shared hosting with a company that doesn’t offer PHP with acceleration).
- cache dynamic output: install the “WP Super Cache” WordPress plugin. Configure and then forget about it; if you create/edit a blogpost, impacted pages are automatically removed from cache.
- optimize CSS and JS: install the “CSS JS booster” WordPress plugin, which (amongst other things) grabs all CSS and JS from WordPress and Plugins and outputs it in one CSS- and one JS-file (some plugins, e.g. Sociable and WordPress Mobile Pack, might need tweaking of the css media-attribute though) UPDATE: CSS JS booster has not been updated since 2010 and I switched to (and later even took over development of) Autoptimize for JS, CSS & HTML optimization.
- optimize images: fire up your favorite photo editor and make that image just a bit smaller, use an acceptable level of compression (I end up between 70 and 80% for JPEG’s, depending on the image) and upload to smushit.com to squeeze out the last optimization-drop (example; I used a 20KB picture from Flickr, resized it to 80%, saved it with 77% compression and smushed it to end up with a mere 6KB).
The impact of a number of these steps can be measured easily; below are the response times of my blog’s homepage (the html including css, js and images) as measured by Pingdom Tool’s Full Page Test.
- default WordPress (on a Linux VPS with 320Mb RAM memory): 6.5 seconds
- (1) with PHP APC activated: 4.1 seconds
- (2) with WP Super Cache: 3.1 seconds
- (3) with CSS JS Booster: 1.3 seconds
So there you have it, from 6.5 to 1.3 seconds in only 5 easy steps! WordPress specific, but easily applicable to other platforms as well. Now go and make your site fast! And then go and make it even faster!