| ID | PPSA-202610-8 |
|---|---|
| Published | 2026-10-21 |
| Private Packagist Cloud | Affected. Fixed on 2026-10-15. |
| Private Packagist Self-Hosted (KOTS) | Affected <= 2.0.37. Fixed in 2.0.38. |
| Private Packagist Self-Hosted (Helm) | Affected <= 2.0.37. Fixed in 2.0.38. |
Summary
An attacker able to add packages in Private Packagist could have set the source URL of a package version, for example in the package's composer.json, to a path on the Private Packagist servers and downloaded another organization's package code as the zip archive of that version. In a repository with multiple packages, the attacker could also have replaced a package's directory with a symbolic link to a directory on the servers and downloaded the files in that directory the same way.
Who was affected
Private Packagist Cloud until the fix on October 15, 2026, and Private Packagist Self-Hosted installations running a version before 2.0.38, if all of the following are true:
- A malicious user can add or edit packages in any organization, for example a package from a Git repository the attacker controls, a custom package, or a mirrored third-party repository whose package information the attacker controls.
- The attacker knows how files are stored on the Private Packagist servers, the internal identifier of the targeted organization and the repository URL of the targeted package.
- The targeted package is read from a Git, Mercurial or Subversion repository, and a copy of that repository was stored on the server that built the archive.
For the symbolic link, the attacker instead needed a Git repository with multiple packages that they control, added to an organization where they can add packages, and had to know the path of the directory to read on the server that built the archive.
On Self-Hosted, only organizations on the same installation could be targeted.
Impact
An attacker could have read the code of a package of another organization, by setting the source URL of one of the attacker's own package versions, for example in its composer.json, so that Private Packagist built its zip archive from the copy of the other organization's repository on the Private Packagist servers, and downloading it.
With a symbolic link in a repository with multiple packages, the attacker could have read the same repository copies, and also any other directory on the server that built the archive that the archive process could read.
The attacker could not change other organizations' packages, archives, credentials, members or settings.
What we did
Private Packagist no longer builds archives from a source URL or source mirror that points to a path on its own servers. Building the archive of such a version now fails with an error that asks for a remote repository URL. In a repository with multiple packages, Private Packagist no longer builds an archive when the package's directory is a symbolic link to a location outside of the repository; the archive fails with an error that asks to replace the symbolic link with a directory. We found this vulnerability during an internal security review.
We reviewed the stored package information of all organizations on Private Packagist Cloud for package versions with a source URL or source mirror that points to a path on the Private Packagist servers, the audit log entries of custom packages added or edited with such a source URL, and the archive job history as far back as it is kept. We found no package version, audit log entry or archive attempting to exploit this vulnerability. To the best of our knowledge, setting a source URL to a path on the Private Packagist servers 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 package versions and audit log entries with a source URL that points to a local path, and for archives built from such versions. It prints one line for each match, and otherwise "No compromising package versions found" and "No compromising audit log entries found". If it reports any match other than the Mercurial packages described below, 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-8"The command has these limits:
- Archive jobs are only kept for a limited time. The command prints the date of the oldest archive job it could check.
- A package version whose branch or tag was deleted is no longer stored, so the command cannot report it.
- Changes to a package's
composer.jsonare not recorded in the audit log. - Package versions of old Mercurial repositories on Bitbucket are also reported, as their source URL has no scheme.
- Archives built through a symbolic link in a repository with multiple packages are not checked.
- Private Packagist Cloud: No action is required.
Start Free Trial
Login to create an organization and start your free trial!