On May 22 and 23, 2026, an attacker published hundreds of malicious versions under historical release tags for four community-maintained Laravel localization libraries distributed on Packagist under the laravel-lang namespace. The attack affected 700+ package versions across four packages β laravel-lang/lang, laravel-lang/attributes, laravel-lang/http-statuses, and laravel-lang/actions β and delivered a cross-platform credential stealer that activates automatically on package installation.
The poisoned tags appeared in rapid succession, many only seconds apart. That automation signature distinguishes this from a maintainer account compromise where a single developer mistakenly publishes a malicious release β the volume and speed indicate scripted, deliberate mass tagging across the entire version history of the affected packages.
How the Attack Worked
The technical elegance here is in what the attacker didnβt do. The official source repositories were not altered. No commits were pushed to the legitimate laravel-lang GitHub repositories. Instead, the attacker exploited a fundamental property of how Packagist β PHPβs central package registry β resolves version information.
Packagist determines what code corresponds to a given version tag by reading that tag from GitHub. The attacker created attacker-controlled forks of the affected repositories and pointed the historical release tags to commits in those forks rather than to the legitimate upstream commits. From Packagistβs perspective, the tag existed and resolved to code β it just wasnβt the code anyone expected.
The result: developers installing any affected version of these packages β including historical versions pinned in composer.json files β would receive the attackerβs payload rather than the legitimate code, without any change to the official source repository being visible.
The Payload
The injected file β helpers.php β was wired into Composerβs autoload.files mechanism. This is PHPβs equivalent of a global initializer: any file listed in autoload.files runs on every PHP request, the moment the package is loaded. There is no opt-in. There is no configuration to disable it. Installing the package and running any PHP code that loads Composerβs autoloader is sufficient to trigger the stealer.
The credential stealer was designed as a comprehensive exfiltration framework. It targeted:
- Cloud provider keys (AWS, GCP, Azure environment variables and credential files)
- Kubernetes and Vault secrets
- CI/CD tokens (GitHub Actions tokens, GitLab CI variables, CircleCI, and others)
- SSH keys and known_hosts files
- Environment files (
.env,.env.local, and application-specific equivalents) - Browser data (saved passwords, cookies, local storage)
- Password manager vaults
- Cryptocurrency wallet files
- Messaging tokens (Slack, Discord, and similar)
The cross-platform targeting β cloud keys alongside browser data alongside crypto wallets β suggests a payload designed to maximize yield across different environments. A developer running the package locally would lose credentials stored in their browser and wallet files. A CI/CD pipeline running the package in a build environment would lose cloud credentials and deployment tokens.
The Packagist Tag Resolution Vulnerability
This attack is a concrete demonstration of a structural trust issue in the PHP ecosystemβs package resolution model. Packagist trusts GitHub for tag resolution. GitHub does not enforce that tags in forks point to commits in the original repositoryβs history. The gap between those two facts is where this attack lived.
Similar mechanics have been used in attacks on the JavaScript and Python ecosystems β dependency confusion, typosquatting, and tag hijacking variations have appeared across npm, PyPI, and RubyGems. PHPβs Packagist had not seen a tag-rewrite attack of this scale before. The Megalodon campaign from earlier this week targeted GitHub Actions workflows through similarly automated mass-deployment techniques.
The difference here is that Megalodon required maintainer credentials (compromised PATs) to push to repositories. The Laravel-Lang attack, by exploiting Packagistβs tag resolution against attacker-controlled forks, required no access to the legitimate repositories at all.
Who Is Affected
laravel-lang packages are widely used across the Laravel ecosystem for localization β multilingual string management is a common requirement, and these packages are maintained by a respected community contributor. The packages have substantial download counts across their version histories.
Any developer or CI/CD pipeline that ran composer install or composer update during the attack window β May 22β23 β and resolved to any of the 700+ poisoned versions is potentially affected. Because the attack rewrote historical tags, developers pinning specific older versions were not protected; the tag they were pinning no longer pointed to the expected code.
The investigation is ongoing. Package maintainers, Packagistβs security team, and security researchers including Aikido Security, StepSecurity, Snyk, and Mend have been involved in documenting the attack and working toward remediation.
What Affected Developers Should Do
Any development environment or CI/CD pipeline that may have installed the affected packages should:
- Immediately rotate all credentials that may have been accessible during the affected period β cloud keys, API tokens, SSH keys,
.envfile contents - Audit all Composer lockfiles for affected package versions and update to verified clean releases
- Review CI/CD pipeline logs from May 22β23 for unexpected outbound connections
- Treat the development machine or build environment as potentially compromised if the package was installed
The legitimate maintainers of laravel-lang packages are working with Packagist to remediate the tag resolution. Until confirmed clean, any installation of these packages from the affected window should be treated as untrusted.
Sources
- The Hacker News: Laravel-Lang PHP Packages Compromised
- Aikido Security: Supply Chain Attack Targets Laravel-Lang Packages
- StepSecurity: Laravel-Lang Supply Chain Attack
- Snyk: Laravel Lang Supply Chain Advisory
- Security Online: Laravel-Lang Supply Chain Attack β RCE Backdoor
- Mend: Laravel-Lang Composer Tag-Rewrite Supply-Chain Attack



