Writing PHP files from Drupal

Author: 
Parent Feed: 

Over the years the security teams consistently shut down projects that were updating modules from Drupal. In Drupal 7, we added a subsystem where you could FTP or SSH back to the server to do that -- and allowed for local writes in insecure setups. In Drupal 8, however, we now have a feature in core that allows us to write PHP files just like that. I feel the community deserves an explanation of why we didn't allow these modules in the past and what is different in the D8 API. The problem is that if your web server setup is such that Apache can write PHP files into directories it serves PHP files from then a poorly written upload script like this one can allow an attacker to upload a PHP file and execute it (or, upload a .module and get Drupal to include and execute it). There are a healthy number of protections in the D8 API:

  1. The PHP files are written into the files directory which has .htaccess protection against executing PHP files.
  2. The name of the files are constructed in a way that an attacker can not reproduce: it depends on the modification time of the directory it is in and a secret value.
  3. If Drupal includes a PHP file which generates an error and thus reveals the file name, an attacker still can't use that file name for an upload. (If the file is deleted and written back then the directory mtime changes, if the file is just opened for writing then its own mtime will be higher than the directory which Drupal refuses to include.)
  4. The directory where the file is not neither writeable nor listable.
  5. The file is not writeable either.

Basically, our hope is that adding this new API does not open new avenues for an attack. For example, if you have local filesystem access then while you could exploit this new subsystem, you also could do other things (like reading settings.php) so then this subsystem does not open new doors for attack.

There is a small new risk. If all the following are true:

  1. Error display is set to screen (should not be such on production).
  2. The PHP code written to disk shows an error revealing the file name.
  3. There is such a "leaky" upload script.

then the attacker has an incredibly short window (a few PHP instructions long) to replace the newly written PHP file with an attack script. If the upload script also is broken enough to chmod the holding directory then this window becomes one second long.

The immediate plan is to use this for the dependency injection container. In the future, Twig and perhaps module upgrades could use it. The code is self contained enough that we could even use it upgrade core.

Original Post: 
RSS Tags: