On 28 March 2021, two commits appeared in php-src's master branch on git.php.net, pushed under the names of Rasmus Lerdorf, PHP's creator, and core developer Nikita Popov. They were titled '[skip-ci] Fix typo' — a subject small enough to skip review and, with the skip-ci prefix, designed to bypass continuous integration as well. The change, in a widely included header, checked a server variable for the HTTP User-Agent and, if it began with the string 'zerodium', executed the rest of the header as PHP code: remote code execution on any server running the poisoned interpreter.

It did not work, and the reason is instructive: the commits were spotted within hours by community members reading the public feed — a commenter flagged the change on the commit itself, and PHP developer Jake Birchall confirmed it executed code from the user-agent header. Popov announced the same evening that everything pointed to a compromise of the git.php.net server rather than any individual account. The commit text itself carried the line 'REMOVETHIS: sold to zerodium, mid 2017', implying the backdoor had been brokered to an exploit vendor years earlier.

The project's response was to remove the asset rather than repair it. git.php.net was discontinued on the spot; the GitHub mirrors, until then secondary, became the canonical repositories; write access moved to the php GitHub organization with two-factor authentication required for membership; and all PHP releases were put on hold for two weeks while the repositories were audited for further corruption. The two commits never reached a single end user.

No end-user impact — both commits were reverted before any release. The real cost was the project's own git infrastructure and a two-week freeze on all PHP releases

The project ran its own git server with a home-grown karma system for write access — a bespoke authentication surface the small core team had to defend entirely on its own.

Commit identity on that server rested on push-time sign-off, not cryptographic signatures, so anyone controlling the server could commit as the project's most trusted names.

The disguise was tuned to the review process: a one-word 'typo' fix, in a header included nearly everywhere, prefixed to skip CI entirely.

The GitHub mirrors that saved the project had spent years as second-class copies — recoverable only because the team chose to promote them under emergency conditions.

Self-hosting version control buys a project nothing except an attack surface it must defend alone. Mirrors only pay off if they are ready to become the source of truth the hour you need them to.

php.net formally put releases on hold for two weeks while the investigation ran, stating the malicious commits were 'immediately noticed and reverted, and thus never reached end users'. The repositories were reviewed for corruption beyond the two commits, GitHub became the permanent canonical home of php-src, and organization membership now requires 2FA. The backdoor's code comment — 'sold to zerodium, mid 2017' — remains public in the commit history; the vendor never confirmed buying it.

FOLLOW THE EVIDENCE

The sources

  1. Changes to Git commit workflow (php.internals #113838) news-web.php.net
  2. PHP releases on hold php.net
  3. [skip-ci] Fix typo (commit c730aa26) github.com
  4. PHP's Git server hacked to add backdoors to PHP source code bleepingcomputer.com