| ID | PPSA-202610-12 |
|---|---|
| Published | 2026-10-21 |
| Private Packagist Cloud | Affected. Fixed on 2026-10-15. |
| Private Packagist Self-Hosted (KOTS) | Affected >= 2.0.34, <= 2.0.37. Fixed in 2.0.38. |
| Private Packagist Self-Hosted (Helm) | Affected >= 2.0.34, <= 2.0.37. Fixed in 2.0.38. |
Summary
When an organization limited Composer plugins to an allowlist, Private Packagist only hid and blocked versions with the type composer-plugin. Versions with the legacy type composer-installer, which Composer also loads and runs as plugins, were still served for packages that were not on the allowlist.
Who was affected
Organizations on Private Packagist Cloud until the fix on October 15, 2026, and on Private Packagist Self-Hosted installations running a version from 2.0.34 to 2.0.37, if all of the following are true:
- The Composer plugin policy under Settings > Security is set to Limit to list below.
- A package the organization uses, but that is not on the allowlist, has a version with the type
composer-installer. - The project installing that version allows the package to run as a plugin in its
allow-pluginsconfiguration incomposer.json, for example with"*": trueortrue, or a developer allowed the package when Composer asked whether to trust it.
Organizations with the Composer plugin policy set to Allow all, the default, were not affected, as all plugin packages are served to them.
Composer also applies the allow-plugins configuration in a project's composer.json to composer-installer packages, so a project that only allows specific plugins by name did not run a composer-installer package missing from the allow-plugins list.
Impact
A malicious package maintainer, or an attacker who took over a maintainer's account, could have published a version with the type composer-installer of a package that is not on the allowlist. Composer could then have installed that version and run its code during composer install or composer update on developer machines and CI servers, with the permissions of the user running Composer. Preventing such code from running is the purpose of limiting plugins to an allowlist.
If Block downloading disallowed plugin versions from existing lock files was enabled, Private Packagist still served the dist file of a composer-installer version referenced in an existing composer.lock. The package page did not mark such versions as uninstallable, and the allowlist suggested when first limiting plugins did not include packages of this type.
This issue did not give access to any data stored in Private Packagist or to other organizations.
What we did
Private Packagist now treats versions with the type composer-installer the same as versions with the type composer-plugin. For packages that are not on the allowlist, these versions are hidden from Composer, their dist files are blocked if downloads of disallowed plugin versions are blocked, and the package page marks them as uninstallable. The allowlist suggested when first limiting plugins now includes packages of this type. The fix was deployed on Private Packagist Cloud on October 15, 2026, and released in Private Packagist Self-Hosted 2.0.38.
Composer clients that cached the metadata of organizations limiting plugins to an allowlist receive updated metadata on their next request.
We checked all organizations on Private Packagist Cloud that limit Composer plugins to an allowlist and none of these organizations had packages with the type composer-installer. To the best of our knowledge, this vulnerability was not exploited on Private Packagist Cloud.
Do customers need to do anything
- Private Packagist Self-Hosted: Upgrade to 2.0.38 or any later version. We recommend upgrading to the latest release. Afterwards, run this command to check your installation for packages with versions of the type
composer-installerin organizations that limit Composer plugins to an allowlist. It prints one line for each such package with the organization and the affected versions, and for each version the number of installs since August 24, 2026, when 2.0.34 introduced the allowlist. Otherwise it prints "No composer-installer versions found in organizations limiting Composer plugins to the allowlist". Install counts only include installs that Composer reported, so a version may have been installed more often than shown. Packages on the allowlist are listed as well; review the packages that are not. If you find a version you do not trust, contact us at contact@packagist.com.kubectl exec $(kubectl get pods --field-selector=status.phase=Running --no-headers -o custom-columns=":metadata.name"|grep worker-) -- /bin/sh -c "/srv/manager/bin/console packagist:audit --vulnerability PPSA-202610-12" - Private Packagist Cloud: No action is required.
If your organization limits Composer plugins to an allowlist, check whether your projects depend on packages with the type
composer-installer. Run this command in each project, it requires jq and prints the name of every such package incomposer.lock, or nothing if there are none:jq -r '(.packages + (.["packages-dev"] // []))[] | select(.type == "composer-installer") | .name' composer.lockVersions of these packages are now hidden from Composer unless the package is on the allowlist. Add a package to the allowlist under Settings > Security if you trust it to run code during installs. If you do not recognize a package, or did not expect it to run as a plugin, review the installed version before allowing it.
Credits
Thanks to Huzaifa Jawaid for reporting this issue.
Start Free Trial
Login to create an organization and start your free trial!