Skip to content
This repository has been archived by the owner on Apr 7, 2018. It is now read-only.

Commit

Permalink
Merge branch 'CVE-2015-5723'
Browse files Browse the repository at this point in the history
  • Loading branch information
beberlei committed Aug 31, 2015
2 parents 1fb268e + a538265 commit 3a7117f
Showing 1 changed file with 181 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
Security Misconfiguration Vulnerability in various Doctrine projects
====================================================================

We are releasing new versions of Doctrine Cache, Annotations, ORM and MongoDB
ODM today that fix a security misconfiguration vulnerability. This
vulnerability was assigned CVE-2015-5723. It requires an attacker to have
direct access to a user of the server to be exploitable. We consider
exploitabilty to be low to medium.

Exploiting this vulnerability can allow attackers to perform local arbitrary
code execution with privleges of other users (privilege escalation).

**You are only affected by this vulnerability, if your application runs with a umask of 0.**

Please update:

- Annotations to 1.2.7
- Cache to 1.4.2 or 1.3.2
- Common to 2.5.1 or 2.4.3
- ORM to 2.5.1 or 2.4.8
- MongoDB ODM to 1.0.2
- MongoDB ODM Bundle to 3.0.1

If you want to check the fix or apply patch manually, we `provide a Gist with all patches
<https://gist.github.com/beberlei/dc6e4b018988cba7e211>`_.

If you cannot upgrade, see our notes below how to mitigate the problem without
having to patch the code.

We want to thank `Ryan Lane <https://twitter.com/squiddlane>`_ for finding the
vulnerability, `Jonathan Eskew <https://github.com/jeskew>`_ from the AWS team
to pass this security vulnerability to us and `Anthony Ferrara
<https://twitter.com/ircmaxell>`_ for helping us discuss and find solutions to
the problem.

Details
-------

Doctrine uses different kinds of caches and some of them read the cached
entries using ``require`` or ``include`` to make use of APC or Opcache.
In case of proxy generation we actually need to execute the code to make
a new auto-generated class part of the code-base.

Doctrine always uses ``mkdir($cacheDirectory, 0777);`` on many of those caches
directories. If your application is running with ``umask(0)``, this allows an
attacker to write arbitrary code into the cache directory which can be executed
with the user privileges of the webserver.

Running your application with ``umask(0)`` is not generally a good idea, but is
sometimes recommended as simple solution to solve filesystem access problems
when a console and a web user both write to a common cache directory. In
combination with a cache that executes the cache entries as code, this can
allow local arbitrary code execution.

The patches released today change all caches that execute code to always use a
default mask of ``0775`` instead of ``0777``.

- In case of Cache and Annotations we solve this by implementing a userland configurable umask
that defaults to ``0002``. We apply this to every mkdir and chmod so that you can reconfigure
to another mask if you must.
- In all the other cases its a hardcoded change to ``0775`` for directories and
``0664`` for files.

We are aware that if you depend on ``umask(0)``, this is a very inconvenient
change, because your code will break when different users write to the same
cache directory.

**We feel it is not safe to make developers and operations responsible to know
how to secure our cache implementations. They are often third party libraries
to other open-source systems, we want them to be safe no matter how users
configure their system.**

Am I vulnerable?
----------------

Your application must run with ``umask(0)`` for this vulnerability to be
exploitable. This must not necessarily be an explicit call to the PHP function,
it can also happen if you misconfigured your shell or webserver to run with
umask 0 by default.

You can easily check this by calling ``echo umask();`` from both the shell and
your webserver. It will return 0, if you are potentially vulnerable.

Second, you must be using using Doctrine with the Annotations FileCache or the
PhpFileCache Cache implementation or one of the ORM or ODM ProxyGenerators. Of
course this vulnerability can also be present in any other library or your own
application, when you dynamically generate PHP code into a directory with world
writable permissions.

Do you provide fixes for all branches of all affected components?
-----------------------------------------------------------------

No, fixes are only applied to the most recent versions of Doctrine components.

If you are running older components and don't want to or cannot upgrade, you
should look into the sections about immediate and proper fixes below, that show
solutions that don't require upgrading your code.

If your system and application are correctly setup, it is also likely that you
are not vulnerable. See the next section for information about that.

Is there an immediate fix when I can't upgrade?
-----------------------------------------------

Yes, as an immediate fix just make sure that your application runs with a
non-zero umask all the time. Call ``umask(umask() | 0002);`` early in your code
to prevent PHP from ever creating world writeable files and directories.

Warning: It can break your application if it relies on running with ``umask(0);``.

This is not sufficient though, because the call to umask is not thread safe and
a call to this function later in the code can reset the umask for all requests
currently running. That means you must identify all code that calls
``umask(0);`` and change it.

When you are unsure if your generated cache is clean, you can regenerate all
files after you have changed the umask of your application.

Is there a proper fix or security best-practive to avoid this issue?
--------------------------------------------------------------------

Yes, the best way to fix this problem is to always execute PHP code for a single
application with the same user, independent of being called from the webserver,
php-fpm or the shell. In this case you can always create directories with the
default permissions of ``0775`` and files with ``0664``:

.. code-block:: php
<?php
// safety measure to overrule webserver or shell misconfiguration
umask(umask() | 0002);
mkdir("/some/directory", 0775);
file_put_contents("/some/directory/file", "data");
chmod("/some/directory/file", 0664);
On most linux distributions it is possible to execute cronjobs or supervisord
jobs with the ``www-data``, ``nginx`` or ``apache`` users that the webserver
runs with.

Another way would be to use more advanced permission systems in Linux such as
``chmod +a`` or ``setfacl``, both of which are not available on all
distributions though.

Isn't everyone just using 0777/0666 everywhere?
-----------------------------------------------

Yes, this practice is extremely wide-spread in many projects. This is why we
think it is very important to make sure your application runs with a proper
umask.

However, in our case the potential vulnerability is more severe than usual,
because we use ``require/include`` to execute the written cache files, which
can allow an attacker with access to a local user the possibility for executing
arbitrary code with the webservers user.

Code that is reading the generted/cache files using ``fopen/file_get_contents``
could "only" be poisoned with invalid or wrong data by an attacker. This is
severe by itself, but does not allow arbitrary code execution.

We want users of Doctrine to be safe by default, so we are changing this even
if it will cause inconveniences.

We have also notified as many OSS projects of this beforehand, mainly through
PHP-FIG, because of the wide-spread practice. Several of them are preparing
security releases for their libraries as well.

Again, the nature of this issue is mostly remedied by **not** running with
umask of zero, so make sure this is the case for your applications.

Questions?
----------

If you have questions you can signup to the `Doctrine User Mailinglist
<https://groups.google.com/forum/#!forum/doctrine-user>`_ and ask there or join
``#doctrine`` IRC Channel on Freenode.

.. author:: default
.. categories:: none
.. tags:: none
.. comments::

0 comments on commit 3a7117f

Please sign in to comment.