5 Answers About PHP Phar Exploitation

In August 2018, Sam Thomas discovered a new way to attack PHP applications. This exploitation works by causing the application to unserialize a data structure controlled by the attacker and leads to the execution of arbitrary code on the attacked system.

Specifically, this attacks utilizes the phar:// stream wrapper which allows access to Phar application archives. The underlying problem is that PHP unserializes a Phar archive once it is first accessed by a file operation (e.g., file_exists()).

In this post, I answer five common questions about this new vulnerability and what it means for your application.

Am I only affected when I’m using phar archives in my application?

Sadly, no. For this exploitation to succeed, it is only necessary to have a file operation such as file_exists() that takes as its input parameter a variable that can be controlled by the attacker. Consider this example:

if(file_exists($_POST['input_path'])) {
  // do something

Assuming there is no further data validation, a user can control which value is passed to the file_exists() call. They might set its value to something like phar://../uploads/example.jpg. If such a piece of code exists in your application and the attacker is able to upload files to your filesystem, you are very likely vulnerable.

But I’m safe if I do not allow upload of .phar files, right?

Not necessarily. When parsing files, PHP does not care about the file extension as long as the uploaded file has a valid Phar structure. Sam Thomas has demonstrated in his whitepaper that it is possible to embed a phar archive in a valid JPG file, so even if you are filtering your uploads for MIME type etc, you won’t be safe from this attack.

What’s the worst thing that could happen if the attacker can successfully unserialize a .phar archive?

By carefully crafting the uploaded phar file, the attacker can trigger system calls, for example using PHP’s passthru() function. This is possible since the __wakeup() and __destruct() methods of a serialized class are automatically called on unserialization. Using this vector, the attacker can overtake the system and is for example able to delete files, access confidential data or use the attacked system for other malicious purposes.

How can I defend myself from this exploitation? There must be a PHP update, correct?

While the author of the whitepaper suggests PHP to change its default behavior and not unserialize phar contents in this unnecessary way, at this point it does not seem very likely that this will happen in the near future. Unfortunately, it is also not possible to disable Phar compatibility for a specific PHP installation.

The only thing one can do as an application developer is to check each file operation and make sure that it is impossible for the application user to set their input parameters to a string starting with phar://.

Which file operations need to be investigated?

You should at least check the usages of the following functions:

  • include()
  • fopen()
  • file_get_contents()
  • file()
  • file_exists()
  • is_file()
  • md5_file()

For an exhaustive list, see the PHP documentation.

Further Reading:

Bernhard Knasmüller on Software Development