Packagist.org maintainer account takeover

What happened?

On May 1st, 2023 between 3:08pm UTC and 4:05pm UTC an attacker accessed four user accounts that had been inactive on Packagist.org for a period of time but still had access to a total of 14 packages. The attacker forked each of the packages and replaced the package description in composer.json with their own message but did not otherwise make any malicious changes. The package URLs were then changed to point to the forked repositories.

On May 2nd, at 7:21 am UTC we were notified by Juha Suni about the change of URL to multiple Doctrine packages. Together with Marco Pivetta (Ocramius) we promptly identified all accessed accounts, disabled access to them and restored the URLs to their previous values. Analysis of the forked repositories showed that no malicious changes were distributed. All accounts were disabled and their packages were restored by May 2nd, 8:20am UTC.

How was this possible and what should you do?

All four accounts appear to have been using shared passwords leaked in previous incidents on other platforms. Please, do not reuse passwords. Make sure you use a unique strong password on every website you create an account on, you can use a password manager to keep track of the variety of passwords for you. We strongly urge all users of Packagist.org to enable Two-Factor-Authentication (2FA). You can do so under Profile ยป Two-factor authentication using an authenticator app of your choice. Please also enable 2FA on your GitHub accounts.

In general we always recommend you review changes you make to your lock files to ensure no untrusted dependencies or external URLs are introduced to your application. Please note that Packagist.org is only a metadata server and package contents are downloaded from a location chosen by the package maintainers.

Private Packagist will store copies of mirrored package contents, so Composer can download them from there, but the lock files will still contain the maintainers' original URLs for reference and as a fallback. Private Packagist Update Review can help you spot metadata changes, like a malicious URL, in the lock file during code review more easily.

What measures did we take?

As a first immediate step we disabled edits of popular packages with at least 50,000 installations entirely. If you maintain one of these packages and need to make changes to it, please contact us by email at contact@packagist.org.

The changes to package URLs were recorded in the Packagist.org audit log. We plan to make this information more easily accessible publicly to allow easier auditing of package metadata. There are already plans to extend the audit log to record both package metadata changes and maintainer data changes in significantly more detail.

Which packages were changed exactly?

The full list of affected packages is as follows:

  • acmephp/acmephp
  • acmephp/core
  • acmephp/ssl
  • doctrine/doctrine-cache-bundle
  • doctrine/doctrine-module
  • doctrine/doctrine-mongo-odm-module
  • doctrine/doctrine-orm-module
  • doctrine/instantiator
  • growthbook/growthbook
  • jdorn/file-system-cache
  • jdorn/sql-formatter
  • khanamiryan/qrcode-detector-decoder
  • object-calisthenics/phpcs-calisthenics-rules
  • tga/simhash-php

Reporting Packagist.org vulnerabilities

If you are a security researcher and know of a Packagist.org vulnerability or would like to do research on Packagist.org, we ask you to please coordinate testing with us to avoid negative user impact, and to disclose these vulnerabilities responsibly. You can reach us at security@packagist.org and we reply promptly to all requests or reports. We of course provide credit and publish details of reported vulnerabilities, see for example CVE-2022-24828: Composer Command Injection Vulnerability or Composer Command Injection Vulnerability.