We were alerted last week of a malware outbreak affecting WordPress sites using version 3.0.2 and lower of the fancybox-for-wordpress plugin. As announced, here are some of the details explaining how attackers could use this vulnerability to inject malicious iframes on websites using this plugin.
Technical details
This vulnerability exploited a somewhat well-known attack vector amongst WordPress plugins: unprotected “admin_init” hooks.
As “admin_init” hooks can be called by anyone visiting either /wp-admin/admin-post.php or /wp-admin/admin-ajax.php, this snippet could be used by remote attackers to change the plugin’s “mfbfw” option with any desired content. This got us asking ourselves, what was this option used for?
We found that this option was being used in many places within the plugins codebase. The one that caught our attention was inside the mfbfw_init() function. This basically displays jQuery scripts configured to work with parameters that were set up earlier, in mfbfw_admin_options().
As you can see from the above picture, the $settings array is not sanitized before being output to the client, which means an attacker, using the unprotected “admin_init” hook, could inject malicious Javascript payloads into every page of a vulnerable website, such as the “203koko” iframe injection we presented last week.
10 comments
The `extraCalls` setting key was used in this particular case, its content was output directly after the jQuery call before the tag was closed. `extraCallsEnable` was also set to “on”. Although other setting keys could have been used to escape the initialization object, `extraCalls` was a much saner, more straightforward and cleaner approach.
Thanks for this, it really makes it clear to me how easily this kind of thing can happen.
And it begs the question – how can I make sure my own use of the admin_init hook does not open up a website to such abuse? Is it enough to make sure all variables are sanitized before storing in the database and displaying to the user?
Authorize, authenticate, validate, sanitize.
The problem wasn’t soley that data wasn’t sanitized, but that the request authorization wasn’t validated before the data was written to the DB. Plugin and theme developers need to be aware of exactly how they’re exposing their settings to the outside world. The WP plugin API has some coding examples on checking access control in this situation: http://codex.wordpress.org/Plugin_API/Action_Reference/admin_init
thanks for the explanation
v3.0.6, the latest version at this moment I write this comment, is still affected by the exploit.
Were you affected and then updated the plugin or were you on the latest version before you got infected?
It seems fixed already, but you need to clean your DB as described in the FAQ section of the plugin’s URL.
I can confirm that as well. The latest release is still infected.
I was in v3.0.2
Comments are closed.