Описание
Security issue with external entity loading in XML without enabling it
Summary
After working on the issue some days, we more and more come to the assumption, that the actual issue is lower in the stack than the Nextcloud Server's PHP code. We were able to isolate it to a few lines of plain PHP code (but seemling only after performing a "Nextcloud login")
Details
After working on the issue some days, we more and more come to the assumption, that the actual issue is lower in the stack than the Nextcloud Server's PHP code. We were able to isolate it to a few lines of plain PHP code (but seemling only after performing a "Nextcloud login"), see POC below.
Randomness
The behaviour seems to depend on some "random" factors. A suggestion at the moment is that it's working on the first run in a PHP/Apache process more often then on reused.
- We were never able to produce it on Nginx with PHP-FPM
- We were never able to produce it on CLI
- We were able to reproduce it with latest maintenance versions of PHP 8.0, 8.1 and 8.2 together with Apache2 on Debian
- We were unable to reproduce it with latest maintenance versions of PHP using Apache2 on Ubuntu, but the original reporter seems to be running on Ubuntu.
We are sorry that we are unable to give a clearer indication here, but think that the issue is to critical to ignore or keep to ourselves, just because we fail to give clear reproduction systems, because to us it seems like any system consuming XML is affected.
The most reliable system to reproduce it on is our "Developer Docker": https://github.com/juliushaertl/nextcloud-docker-dev/#standalone-containers but that comes with quite some overhead. The enabled PHP modules and PHPINFO output is available here https://gist.github.com/juliushaertl/b458983b5fe87b31bd98ff2dc2468e97 On that system a Nextcloud user admin with password admin is automatically created and the attack can then be executed with a PROPFIND against the dav endpoint:
We hope that you can shed light on the situation, to help keeping the PHP world secure, by either confirm there is an issue somewhere inside PHP, libxml2, Apache2 or something else, or pointing us to something that brings clearness why it only happens sometimes.
PoC
If you don't want to run code from our servers, you can replace https://bin.icewind.me/r/p0gzLJ
with a link of your own, and make it serve the following content:
The problem we are now facing is the following:
In most cases we correctly receive:
the reporter mentioned that when this happens we should try to run it multiple times, and indeed on some systems we received a different response after some runs:
Mitigation
Our current "fix" to the problem is to set an external entity loader (although it's disabled by default and never enabled actively on our side)
In most cases that leaves the response unchanged with:
But in "successful" cases it now only responds with the following instead of the base64 encoded password file:
Interestingly setting the entity loader to null is not enough and still leaves the system vulnerable:
Impact
- What: The result is a XXE with potential to escalate into a RCE
- Who: Every application/library/server that is parsing/interacting with XML documents
Пакеты
< 8.0.30
8.0.30
Связанные уязвимости
In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.
In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.
In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.
In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* be ...
Уязвимость интерпретатора языка программирования PHP, связанная с неверным ограничением XML-ссылок на внешний объект, позволяющая нарушителю вызвать отказ в обслуживании или получить несанкционированный доступ к конфиденциальным данным