PHP 5.2.7 and ZipArchive::extractTo()

165 days ago I was sitting at a customer’s place and were auditing a large scale web application. The audit was mainly a blackbox penetration test to check if an attacker could attack the application with zero knowledge. However when we found something interesting we were also able to look into the code and check for the exact problem.

The web application in question was one of those big sites that mainly work on user generated content. One of the features of this site is that users can upload ZIP archive files that are then unpacked and added to the users “workbench”. So without knowing anything about the internal implementation I started throwing malicious and broken ZIP files at the application. I created them with my favourite hex editor, by just changing random (or not so random) bytes.

Of course I also changed the filenames inside the archive, added some ../ components and tried if the stone old bug of directory traversal during unpacking worked. And guess what… It worked… I suddenly was able to write anywhere the web-server user was allowed to write to, which is very nice when you can drop new .PHP files to some writable directory inside the document root.

Then the next step was to look at the actual implementation and find out what cause the bug, to give directions to the developers how to fix the problem. It turned out that the application was just calling the ZipArchive::extractTo() function to unpack the files to some temporary directory. This directory was then traversed and every single file or subdirectory added to the “workbench”, followed by a deletion of the temporary directory.

Basically that meant the directory traversal vulnerability was inside ZipArchive::extractTo(). Therefore I reported the problem to security@php.net on the same afternoon I found it, which was 165 days, nearly half a year ago. I also released an advisory about this yesterday, which is available here. The release actually happend BEFORE the official announcement of PHP 5.2.7 on the PHP website, but because I provided the download link to the tarball within the advisory everyone reading it was already able to download and update. Well actually the frontpage of PHP.net still lacks the announcement.

Unfortunately when PHP 5.2.7 was released, it came with a release announcement and a changelog that do not document the security related change in the ZipArchive::extractTo() method at all, which is very unfortunate because from looking at the other reported security problems, the ZipArchive problem seems the most problematic one in real world situations.

For the future, the PHP developers should create some protected wiki page where they write down all the reported security bugs. This might help them not to forget about security problems when they release half a year later…

Ohh, btw… With the release of PHP 5.2.7 I also ported Suhosin-Patch to it. Additionally the new Suhosin release  contains a simple bugfix for unaligned memory access inside the Zend Memory Manager protection. A bug that stopped Suhosin from working at all when you used a compiler like GCC in combination with an architecture like Sparc.