Security Vulnerabilities

Out of the blue today, a user of one of my plugins contacted me to ask why I was so slow in patching a security vulnerability in my system.

The question came as a complete surprise.

Apparently, back in January, someone discovered a potential security hole in one of my plugins, WP Publication Archive.  The frightening thing about the report, though, was the fact that he never bothered to report the vulnerability to me so I could fix it.  Instead, an open report sat there on his site, and was then picked up by a few other security sites and syndicated across the Internet.

Had this user not contacted me, I would never had known about this issue.  And I can’t fix something if I don’t know it’s broken.

The Hole

WP Publication Archive uses a proxy file to load a remote file as an attachment so it can be downloaded by the browser.  Here’s the entire source of the “vulnerable” file:

[cc lang=”php” lines=”60″ width=”580″]
if ( ! isset($_GET[‘file’]) )
die();

require_once(‘../lib/class.mimetype.php’);
$mime = new mimetype();

$fPath = $_GET[‘file’];
$fType = $mime->getType( $fPath );
$fName = basename($fPath);

$origname = preg_replace(‘/_#_#d*/’,”,$fName);

$fContent = fetch_content( $fPath );

output_content( $fContent, $origname );

function fetch_content( $url ) {
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_HEADER, 0 );

ob_start();

curl_exec( $ch );
curl_close( $ch );

$fContent = ob_get_contents();

ob_end_clean();

return $fContent;
}

function output_content( $content, $name ) {
header( “Expires: Wed, 9 Nov 1983 05:00:00 GMT” );
header( “Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT” );
header( “Content-Disposition: attachment; filename=” . $name );
header( “Content-type: application/octet-stream” );
header( “Content-Transfer-Encoding: binary” );

echo $content;
}
[/cc]

In reality, there isn’t a security hole here.  It was reported that this file would include a remote file, thus opening your site up to the possibility of remotely executing malicious code (along the same vein as the TimThumb exploit from several weeks ago).

But this is not the case.

Nothing is included from the remote file, it only downloads the file from within the browser.  So the worst you could do is intentionally download a malicious file as an attachment.  But it also does open your site up to being used as a remote proxy for files you don’t want passed through your server.

So needless to say, it did need to be patched.

So I took some time tonight to sit down, fix a couple of other bugs, and add some code to quickly plug that hole.  It’s not a permanent fix, but does prevent the immediately apparent proxy exploits.  A more elegant patch is already in the works.

Why I’m Upset

But the issue here isn’t really the seemingly insecure code, or even that I had to spend extra time fixing the code.  It’s that a vulnerability was detected and, rather than being reported to me, was posted in a public forum.

For those of you who know, the standard process for reporting any potential vulnerability or exploit is to contact the original author and give them a reasonable amount of time to create a patch before disclosing a 0-day hack to the rest of the world.  Developers need a chance to take action to protect their users’ sites.  It’s common courtesy in just about every developer community in existence.

So I contacted every site that posted information about this security hole, expressed my frustration that they posted it without contacting me, and asked what could be done in the future to prevent this kind of communication breakdown.

One of the reporters, who is also a respected member of the WordPress community, got in touch with me immediately.  He was only recycling a notice he’d seen on another site and didn’t realize that I hadn’t been contacted by the original author.

The original reporter, however, was somewhat less useful:

[O]ur policy is immediate, full disclosure. We also release a variety of tools to aid in the security testing process. It must be stressed that the burden of writing secure code is that of the developers. We encourage you to learn more about secure programming practices.

Am I responsible for writing secure code?  Absolutely.  And I test all of my code to the best of my ability before I release anything.  But just like every other developer on the market, I make the occasional mistake.

Nobody’s perfect.

Had I been notified about this bug and given time to fix it, I would have.  And in doing so, I would have helped make several sites somewhat more secure.

The Real Issue

The real problem here isn’t the security vulnerability, or even how it was reported.  It’s how the community as a whole functions.

A few years ago, I discovered a nifty WordPress plugin on Google Code that let you create a file/document archive on your site.  I loved it!  I used it on my sites, on client sites, and talked it up at WordCamp.

Then, in 2007, the original author abandoned the project.

The next version of WordPress introduced changes that broke the plugin.  So I took the time to re-write it, clean up the code, and eventually update it to use Custom Post Types.  I placed my fork of the plugin in the official plugin repository and all was good.

This is how the community is supposed to function.  Developers help one another out.  If one guy can’t keep going on a project, someone else can step in and take over.  That’s the beauty of open source.

The problem with the security vulnerability wasn’t actually with my version of the plugin, but was reported against the pre-fork version hosted on Google Code.  I’ve been able to verify that the current release doesn’t suffer from the same issues, and have proactively patched the one issue that might crop up as a result of this report.

Unfortunately, the original reporter didn’t contact me about the issue, so I couldn’t clear things up.

And subsequent reporters actually linked the report back to my post-fork version of the plugin, essentially linking the new, secure versions to the old, insecure one.

On the one hand, we have developers going out of their way to help one another.  On the other hand, we have developers sitting on their laurels and mis-reporting information that ends up hurting one another.

The real problem here is one of a massive communication breakdown.


Update

One of the first re-posters of the security notice has clarified things on his site to explain that the vulnerability is actually present in the old, abandoned pre-fork version of the plugin.

The original poster has re-scanned the updated version and verified that no vulnerabilities were detected in the current release. His notice remains on the site, though, as it is accurate for the pre-fork version that triggered it in the first place. However, anyone can contact him directly to verify that the current version is tested to be secure.