Highway To Plugin Danger Zone

Danger ZoneThis post is dedicated to Mark Jaquith, who donated to help me get to WCSF. Thank you, Mark!

There’s nothing wrong with using someone else’s code. All of us do it. That’s how we make something new: by building off the old. And we all build code that relies on someone else, even when we write operating systems. Everything is interdependent, and that’s okay. The problem with relying on someone else’s code, is that you’re open to their vulnerabilities.

Recently there was a kerfluffle about TimThumb, where the community came together and made a script, used by many themes and plugins, better and safer. This was an awesome moment, where we saw disparate strangers overcome FUD and live up to the dreams of Open Source.

In more recent days, there have been a lot of problems with the Uploadify script, to the point that Sucuri wonders if it’s the new TimThumb when it comes to overuse and vulnerability. Unlike TimThumb, Uploadify isn’t actually insecure due to a bug, but the design of how it works is insecure. Yes, it’s insecure by design. Uploadify allows easy multi-file uploads to your site, but it does it without integration with any user verification, so basically anyone who knows where the file is can upload anything they want to your site.

Uploadify offers some security suggestions, which encourages you to use the right folder permissions, keep the file outside of your public_html, and use SSL. The problem there is you’re still not checking to make sure that the code is only accessed by the right people. This isn’t a flaw in Uploadify. It’s a flexible product that can be used with anything, so they don’t want to lock it down to just WordPress, Drupal, Joomla, or whatever. This is, alas, the reason it’s so dangerous. Anyone can hook into it, if you don’t make it secure enough.

Now. A handful of WordPress plugins have been closed due to uploadify exploit potential (between 10 and 20). Not a lot, when you think about it. That’s because, perhaps surprisingly, not as many people are using it as you’d think. In part, this is from WordPress’s shift to plupload in WordPress 3.3, which allows you to hook into it in themes and plugins. By the way, I recommend you use plupload, because if you’re going to rely on third party code, it should be the one that comes with WordPress core.

Beware! Insecurity AheadThe point is not to not use third party code, however, but to use it wisely and to use it safely. It’s your responsibility as a developer to make sure your plugin is secure, and to know what it does. If you don’t understand how someone else’s code works, don’t use it in your plugin, because by using it, you are now responsible for updating it, securing it and keeping it safe. How can you do it if you don’t get it? Furthermore its your responsibility to educate your users as to what a plugin does and how you’ve secured it. This is open source code, the bad guys can already peek in and see what’s up. If they know, then you owe it to the users to arm them with education.

The weakest link in the security chain is the education of the end users. The servers, we hope, know what the heck they’re doing. Ditto the software writers. But the users, they’re often the new guy, the one who doesn’t know what’s what yet, and they trust you. They trust you do your best. Note, I am not saying they trust you to be perfect. Anyone who expects perfection is ridiculous. We all desire it, of course, but you cannot expect it unless you yourself can deliver it. Can you? I thought not.

Alright then so what can you do to protect uploadify and similar scripts? First, lock it so it’s only accessible from the WordPress dashboard panels. If you can only get to it via WP, then you’ve locked yourself so no non-logged in users can access the tool. Then if you slap this code into the top of your file, no one can access it directly:

if ( ! defined( 'ABSPATH' ) ){ die( 'Direct access not permitted.' ); }

Next we should look into how we check for the user. Can any member of your site upload? Probably not. So let’s use capabilities and roles to lock it all down and make sure only the right users have access. We can use two simple lines to verify the user is logged in, and has the right capabilities to upload. The ‘manage_options’ cap is for Administrators, so loosen it up as you need:

if ( ! current_user_can('manage_options') )
die( 'Not allowed to upload.' );

You can hook an upload handler up as an AJAX handler via WP’s admin-ajax.php, per AJAX in plugins. If you need a non-AJAX handler, you can handle form submissions on your plugin admin pages. Going through WP gets you authentication and capabilities checking, and easy usage of nonces (see wp_create_nonce() and related links at the bottom of that page for more info).

There are of course more ways to secure things. There are nonces and AJAX, as well as using WordPress’s image tools to help double check if a file really is an image. After all, not everyone can use .htaccess, and some servers are silly enough to let you run a php file with a jpg extension.

But all that really only works if you want to restrict your uploads to members of your site. What if you want to let anyone upload an image? Honestly, you should re-think that. You are not imagur or imageshack. They have layers of server protections which you don’t, and they have levels of checks and balances in software written specifically for image uploads and protections. You don’t. They are a tool specifically for the job of images. WordPress is not. Do you see where I’m going? Do you really need to allow images be uploaded to your site? I bet you don’t.

One Insecure Link in the ChainShortly after TimThumb was exploited, it was yanked from the theme repository. Since WordPress 3.3 no theme can contain TimThumb. From what I can gather, part of the reason is that code like that should be a plugin, not a theme. But personally, I think that both TimThumb and Uploadify should have official plugins (supported by the original/current developers), and anyone who wants to use that code can hook into those plugins. Then, if there’s an exploit, it’s one plugin to fix and not a couple hundred.

Of course there are as many flaws with that as with any other approach. If the original devs don’t want to support a plugin for WordPress or any other platform, the users would be SOL.

StudioPress Theme of the Month

Comments

  1. (away from the specific security concerns…)

    The underlying issue is that we face the expectations of users, none of which have to match our expectations.

    The most common and easy to understand example I am used to using is that of Avatars. Back in the bbPress days (1960s I think) the single biggest gripe from “end users” (not website admins) was the ability to upload an avatar. A forum user is far more invested that someone commenting on a blog post, which has a tendency to be far more sporadic; and they wanted to have something specific to that site.

    Telling people to go to a different, non-affiliated website (gravatar), sign up for another account to a different system, upload data there, then ensure that they used the same email address on both systems, and to ensure that they were happy for that avatar to be seen whenever the user signed into any of the 100 of millions of WordPress or bbPress sites… well thats mental.

    As geeks, we see the advantage, to end users, they just want to solve the problem at hand.

    And thats where things like Uploadify, and Timthumb come in (etc). It gives people who are not hardcore developers the ability to give their users something they want and need, without having to have the word “ninja” in their job title.

    Sometimes in WordPress land, indeed in Open Source land, we fall behind the “veil of ignorance” in believing that people either have the time or ability to educate their users to how our program works.

    As we become more “social”, as we become more used to the ability to “share”, as websites move away from 1-to-n to n-to-n systems, we also need to be adaptive to the needs and expectations of the end user, and they rarely equate to those of the developer/admin.

    • Ninja is such a loaded term these days too. My fear with third party libraries is that it lends a false sense of security to the developer. They trust this tool, as they trust WP etc, and it let’s them down. Drawing the line between third party and well supported tool is perilously thin. Why do I think jquery (a third party library WP uses) is okay, but get worried for TimThumb? Certainly it’s not just because one was recently exploited.

      I worry about all the code ‘we’ don’t write, and just shove in trusting it will work. Look at TinyMCE and the woes it brings upon us. It’s a great idea, but now everyone is at the behest of core devs to make sure we’re safe.

      For me the difference is in the number of people behind WordPress, the volumes of users, and the hordes of programmers and code jockeys who step in and help, and then the core devs. And we know, we know, WordPress is well tested by thousands before it goes live. We know because they’ve earned our trust. TimThumb, for all I malign it, earned that trust too, by fixing and working together to get it right. But it’s the people who use it in their themes and plugins who I don’t trust, because many of them walked away.

Trackbacks

  1. [...] as I get addresses) and a lot of blog posts to write. Yikes! I did one for Mark Jaquith on Monday: Highway to the Plugin Dangerzone (I wrote it before I knew Tom Cruise and Katie Holmes split). Everything else is on my to-do list [...]

Half-Elf? Try Half OFF WordPress ebooks!