Open Source Security

Composer/PHP Package Supply Chain in 2026

PHP's Composer and Packagist ecosystem has quietly improved its supply chain story. Here is where things actually stand in 2026, and what PHP shops should do now.

Shadab Khan
Security Engineer
8 min read

PHP gets treated as an afterthought in supply chain discussions, which is unfair. The Composer and Packagist ecosystem is smaller in absolute terms than npm or PyPI but serves an enormous installed base of production applications, and in 2026 it has quietly accumulated most of the same supply chain controls as its more visible peers. The story is not as flashy because there was never a single "everything changes now" moment, but the current state is a real improvement over where the ecosystem was even two years ago.

What does Packagist actually do to protect publishers in 2026?

Packagist requires two-factor authentication for publishers of packages above a modest download threshold, enforces a verified email and GitHub account on maintainer identities, and has explicit takeover-prevention controls for abandoned packages. The ownership transfer process went from "email the admins and hope" to a structured flow with waiting periods and notification of prior maintainers. Package deletion requires justification and leaves a visible marker on the package page rather than silently erasing the record.

None of this is novel compared to what npm has done, but all of it represents real progress over Packagist's earlier state, and together it closes off the easiest attacker paths. The remaining weaknesses are on the consumer-verification side rather than the publisher-protection side; Packagist itself has done most of the work a registry can reasonably do alone.

How does Composer handle integrity verification?

Composer's lockfile (composer.lock) captures the exact version and source URL of every dependency, and recent versions include integrity hashes for each package. The --prefer-dist mode, which is the default for most installs, fetches packaged archives rather than cloning git repositories, which gives Composer a well-defined artifact to hash and verify. Running composer install against a lockfile is deterministic and refuses to proceed if the registry serves different content than the lockfile expects.

What Composer does not do by default is enforce signature verification on those archives. Composer can verify GPG signatures on tagged releases if the secure-http and related settings are configured, but the defaults are permissive, and the signature checking path is used by a small minority of projects. This is the single largest gap between Composer's supply chain posture and what the tooling could reasonably achieve, and closing it is mostly a matter of configuration rather than new features.

What is the state of advisory tooling for PHP?

The Friends of PHP security advisories database has been the primary signal source for years, and composer audit has integrated it natively since Composer 2.4. The workflow is clean: run composer audit in CI, get a list of vulnerabilities in your current lockfile, fail the build on findings you do not have an explicit exception for. The advisory coverage for popular Symfony, Laravel, and framework-adjacent packages is good. Coverage thins out for long-tail packages, which is the same pattern you see in every curated security database.

Tools like Roave Security Advisories complement the built-in audit by adding a meta-package to your composer.json that refuses to install known-vulnerable versions during resolution rather than flagging them after. This is a stronger posture because it prevents bad versions from entering your lockfile in the first place, and it is cheap to adopt. Every serious PHP project I audit should have Roave Security Advisories in its dependencies; the ones that do not almost always have historical vulnerable versions lingering in the graph.

How should teams handle Packagist vs. private Composer repositories?

The pattern for any PHP shop past trivial size is a private Composer repository layered over Packagist, typically Satis, Packagist.com for hosted, or Artifactory for heavier shops. The private repository serves three purposes: caching upstream packages for build reliability, hosting internal packages, and enforcing policy at a central point.

The configuration detail that catches teams is the interaction between multiple repository definitions in composer.json. Composer will search repositories in order, and a misconfigured setup can silently fall back to Packagist for an internal package name, which is the PHP equivalent of the dependency-confusion attack that hit npm and PyPI. The defense is to scope internal packages under a specific vendor prefix and to use Composer's exclude configuration to prevent Packagist from serving those prefixes. Every internal Composer setup should have this configuration audited; the default behavior is not safe for projects that mix internal and external packages under common vendor names.

What about install scripts and autoload vulnerabilities?

Composer runs scripts defined in composer.json at various lifecycle points, and the composer install flow can execute code from the installed packages' own definitions. This is the PHP analog of npm's post-install scripts and carries the same risks. Composer 2.x added --no-scripts and improved the controls around when scripts run, but the defaults are still permissive, and a compromised package can execute arbitrary PHP during install.

The standard mitigation for CI is to run composer install --no-scripts when the scripts are not necessary for the build, and to carefully audit which scripts are actually required. For the scripts you do run, the source of truth is whatever composer.json said at the time of install, which means you are implicitly trusting the package maintainer's choices. For high-trust dependencies you should review install scripts the same way you would review any code running in your build environment.

How does the PHP ecosystem handle signed releases and provenance?

Unevenly. Composer has supported GPG-based signing for years, but adoption is low. There is no equivalent of npm provenance or PyPI attestations on Packagist as of 2026, though proposals have surfaced periodically. The practical result is that PHP supply chain verification today leans heavily on the combination of registry integrity (trust Packagist to serve what it claims), lockfile hashes (verify that what you get matches what you expected), and advisory tooling (catch known-bad versions).

This is an acceptable posture for most applications, and the missing attestation layer is a gap rather than a crisis. Expect Packagist to announce something in this space in the next cycle or two; the direction of travel in the broader ecosystem is clear, and the PHP community usually adopts these features with some lag but adopts them. If you are publishing widely-used PHP libraries, keep an eye on the Packagist roadmap and be ready to adopt provenance when it lands.

What is the realistic supply chain checklist for a PHP shop today?

The short version: pin Composer to version 2.4 or later, require 2FA on all Packagist maintainer accounts for your organization's packages, add Roave Security Advisories to every application, run composer audit in CI and fail on findings, use composer install --no-scripts in CI unless scripts are specifically required, use a private Composer repository with explicit vendor scoping to prevent dependency confusion, and keep your lockfile committed and enforced.

None of these are surprising if you have done this for other ecosystems, and none of them are free, but the aggregate effort is a few days of configuration work and pays ongoing dividends. The PHP shops I see doing the best work are the ones that treat this as standard infrastructure rather than a security-team project.

How does the Symfony and Laravel ecosystem influence the broader picture?

More than their market share would suggest. Symfony and Laravel together account for a huge fraction of modern PHP applications, and both frameworks are aggressive about pushing security updates and coordinating advisory releases. When the Symfony security team publishes an advisory, the ecosystem moves fast to patch; when Laravel updates its security baseline, the downstream application community follows. This means that for projects built on these frameworks, the supply chain signal is stronger than it would be for raw Composer usage, and the average time from advisory to patched deployment is shorter than it used to be.

For shops not on these frameworks, or on heavily-customized forks, the same ecosystem-level feedback loop does not help, and you have to do more of the work yourself. This is another place where conformity to the mainstream ecosystem has security benefits that are easy to undervalue until you need them.

How Safeguard.sh Helps

Safeguard.sh audits Composer configurations for the dependency-confusion risk introduced by overlapping repository definitions, enforces that Roave Security Advisories or equivalent controls are present in your application roots, and tracks advisory lag across your PHP repositories. We flag packages whose maintainer ownership has changed recently, surface install scripts that would run during CI, and integrate with your private Composer repository so policy is enforced at the resolution layer rather than after the fact. The goal is PHP supply chain posture that matches the actual maturity of the 2026 tooling, rather than the out-of-box defaults that are still too permissive for production systems.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.