WP Super Cache is a full page caching plugin for WordPress. It creates static pages that are served quickly by the web server. Sometimes however, users still want parts of their pages to remain dynamic and be non static. That’s where mfunc, mclude and dynamic-cached-content came in.
Unfortunately it was reported recently that remote visitors to sites using the plugin could execute any code they like by simply leaving a comment containing the right mfunc code. These functions are now disabled by default, and a filter removes harmful code from comments but if enabled they pose a security risk. I considered adding a security code to the mfunc tag but unfortunately the best way of dealing with this problem is to replace it completely with something different. The next release of the plugin will do away with mfunc, mclude and dynamic-cached-content entirely.
The new dynamic cache system
The development version of WP Super Cache has already been updated with a new filter based system. It uses a cacheaction filter called “wpsc_cachedata”. This filter runs when a page is first cached and also when a cached page is subsequently served. It also runs when caching is disabled for known users, something that has always been broken when using mfunc.
Almost all the data that is displayed on your website will run through the cacheaction filter “wpsc_cachedata”. When a page is first cached, the data that is shown to the first visitor of that page goes through that filter. The second visitor gets a cached page and that page too goes through the filter. What this allows us to do is define a template tag (or more than one) that a function hooked on that filter can search for in the filtered data. It can replace that tag with some other text, usually derived from code that has to run on each request. The visitor is then shown the page with the replaced tag.
The readme.txt hasn’t been updated yet but an example plugin, dynamic-cache-test.php is included in WP Super Cache. It’s fairly simple but it’s documented so it should be easy enough to follow. A template tag is inserted at the bottom of the page using the wp_footer action, and a filter then replaces that tag with text and the current server time. That test plugin replaces mfunc code that would look like this, excluding the necessary code to hook on to wp_footer and print it.
<!--mfunc echo "<!-- Hello world at " . date( 'H:i:s' ) . " -->"; -->
<?php echo "<!-- Hello world at " . date( 'H:i:s' ) . " -->" ?>
WP Super Cache has it’s own action hooks using add_cacheaction() and do_cacheaction(), and work like WordPress actions or filters. The reason the plugin needs those is because they are available before WordPress is loaded. They allow developers to hook into the plugin from the very start of the PHP process and modify how it works using plugins. Those plugins are usually copied into wp-super-cache/plugins/ but I encourage you to move that directory elsewhere because when WordPress updates the plugin it will delete any custom changes you make. The next time a new version of WP Super Cache comes out WordPress will delete the wp-super-cache folder, replacing it with the new update. In your wp-config.php set
$wp_cache_plugins_dir to the location of the new plugins directory.
If you use this filter system in your own plugin for distribution do not ever define the template tag for the user. Let the user decide what it is or generate a random tag and save it somewhere. It’s important to keep the tag secret so visitors cannot trigger your function maliciously. It is however better than the remote user running any code they like as was the case with mfunc!
I hope to release a new version with this code late next week. If your plugin or site uses mfunc please download the development version on a test server and start the process of updating your code.
On the other hand, if you don’t want to update your mfunc tags you could try W3 Total Cache instead. It uses the mfunc tag with a secret code.