This repository has been archived by the owner on Apr 7, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
181 additions
and
0 deletions.
There are no files selected for viewing
181 changes: 181 additions & 0 deletions
181
...drafts/security_misconfiguration_vulnerability_in_various_doctrine_projects.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:: |