Cybersecurity

Laravel-Lang: Every Git Tag, Rewritten — The 15-Minute Supply Chain Attack That Backdoored 700+ Versions Of A Package Half The Laravel World Has Installed

2026.05.25 · 33 views
Laravel-Lang: Every Git Tag, Rewritten — The 15-Minute Supply Chain Attack That Backdoored 700+ Versions Of A Package Half The Laravel World Has Installed

On May 22 an attacker with push access to the Laravel-Lang GitHub organization did not commit malicious code. They rewrote every existing git tag in four popular Composer packages to point at a new malicious commit — meaning every previously safe version constraint became unsafe overnight. What happened, why this attack class breaks Composer's normal defenses, and the exact lockdown checklist every Laravel team needs to run this week.

If you maintain a Laravel application, stop reading after this paragraph and go check whether your composer.lock has been re-resolved against laravel-lang/lang, laravel-lang/attributes, laravel-lang/http-statuses, or laravel-lang/actions on or after 22 May 2026. If yes, treat your CI environment as compromised, rotate every secret the CI runner can see, and audit outbound network connections from the runner since the 22nd. Everything below explains why.


On Friday 22 May 2026, inside a single ~15-minute window, an attacker with push privileges to the Laravel-Lang GitHub organization rewrote every existing git tag — across four heavily-used Composer packages — to point at a new commit that backdoors anything that pulls them. Over 700 versions were re-pointed. The four packages are translation/locale helpers that ship in approximately half of the production Laravel applications in the wild. They are sub-dependencies of dozens of starter kits and CMS templates. If you have ever run composer require laravel-lang/lang you are inside the blast radius.


1. The Attack That Composer Was Not Designed To Catch


Most supply-chain attacks publish a new "innocent-looking" version and hope people upgrade. Composer's defaults catch a lot of those: pinning to a specific version, locking with composer.lock, and Packagist's signed-tag heuristics raise alarms when a fresh version appears unexpectedly.


This attack did not publish a new version. It rewrote the history of versions that already existed. The git tags v1.0.0, v6.4.3, every v..* you had ever previously installed — all rewritten to point to one malicious commit instead of the original benign one. The result: a composer.json that says "laravel-lang/lang": "^14.0" and a composer.lock that says "this specific tag" — neither protects you. Both resolve, on re-fetch, to the rewritten tag, which fetches the malicious blob.


Worse: the malicious commits add src/helpers.php to the Composer autoload.files map. That means the payload runs at autoload time — the very first line of every web request, every artisan command, every queued job. There is no "vulnerable function call" to grep for. The mere act of booting the framework executes the malware.


The payload itself contacts a typosquatted command-and-control domain (flipboxstudio.info), drops a PHP loader and an ELF binary into /tmp, and exfiltrates the environment variables visible to the process. On a CI/CD runner that means every secret the runner has access to: AWS keys, GitHub Actions GITHUB_TOKEN, deploy SSH keys, database passwords, Stripe live keys, Mailgun keys. Then it self-deletes its on-disk artifacts and continues running in-memory.


2. Why This Attack Class Is Strategically Important


This is the second big "tag rewrite" supply chain attack the industry has seen in 60 days (after a similar Python poetry ecosystem attempt earlier in May). It is the third or fourth credential-leak-to-supply-chain pivot in 2026 — the same class of attack as the May 16 Grafana codebase theft and the May 22 Panasonic Avionics breach, both of which started with a stolen GitHub token.


The pattern is now well-established. Attackers compromise developer credentials (a phished maintainer, a leaked Personal Access Token, a token that survived in a public commit) and then weaponize the organization's git history instead of pushing a recognizable malicious version. This breaks every supply-chain defense that assumes versions are immutable.


Strategically, this means three things are now table stakes for any team that pulls open-source dependencies:


First, pin to commit SHAs, not tags, for any package whose maintainer has ever shown signs of credential hygiene problems (any one-maintainer popular package qualifies). Composer supports this via the #sha syntax — the cost is one extra line in composer.json and a more thoughtful update process. The benefit is that tag rewrites cannot affect you.


Second, monitor the GitHub Repos API for tag-shape changes on your critical dependencies. A free GitHub Action or a 30-line script can alert when a tag's SHA changes — which should never happen in normal operation. If it ever does, you have a 15-minute warning window before the new tag propagates to Packagist's CDN.


Third, scope your CI tokens viciously. The blast radius of any supply chain attack equals the secrets visible to the build runner. The convenience of a single "deploy" token with access to staging, production, and AWS is exactly the convenience this class of attack monetizes. One token per environment, per stage, rotated on a schedule.


3. The Composer-Specific Hardening Every Team Should Ship This Week


Beyond the universal lessons, four steps are Composer/Laravel-specific and worth doing this sprint.


Pin via composer.lock and run composer install --no-scripts in CI. The --no-scripts flag prevents the autoload-time payload from firing during the install step itself, buying you a layer of defense if your audit catches the issue before deploy. (Production runtime is a different question — see below.)


Switch deploy-time to composer install --prefer-lock --no-dev and verify the resolved hashes against a snapshot you took before 22 May. Mismatches indicate something downstream has been rewritten.


Enable Composer's audit command in CI (composer audit --abandoned=report) and let it block PRs on advisories above a chosen severity. The Laravel-Lang advisory has been published to the FriendsOfPHP/security-advisories database, so any team running composer audit will see it.


Mirror critical dependencies into your own Composer repository (Toran, Satis, or a private Packagist instance). The mirror gives you a tamper-evident snapshot — if upstream tags get rewritten, your mirror still has the old SHAs and the diff is loud.


4. The Specific Remediation Steps For An Affected Project


If your composer.lock has been re-resolved against any of the four packages since 22 May 2026 — assume compromised. The order of operations:


Step one: rotate every credential the CI runner has access to, starting with anything with production scope. AWS access keys, deploy keys, GitHub PATs, Mailgun, Stripe live keys, S3 keys, database passwords accessible from CI. Do not skip the "we don't use that one anymore" credentials — the attacker does not know your intentions.


Step two: invalidate every JWT signing secret and every API token that was readable to the runner. Force re-issue. Yes, your users will need to re-login. That is the right outcome.


Step three: review outbound network logs from the CI runner since 22 May. Anything to flipboxstudio.info or any unfamiliar IP is the smoking gun. Block those domains at the network egress filter.


Step four: pin the four packages to known-good SHAs. The Laravel-Lang maintainers have published the last-known-good commit SHAs for each tag at the GitHub issue (#8295 in Laravel-Lang/lang). Use Composer's #sha syntax to pin against those, push the change, re-run a clean composer install, and verify the autoload map no longer references src/helpers.php.


Step five: remove the package entirely if your application has any translation strings you could otherwise own in-app. Laravel has supported native translation files since the framework's first release; the laravel-lang packages are a convenience layer, not a necessity.


5. The Wider Pattern And What It Costs The Ecosystem


The Composer ecosystem is built on trust in maintainers. The maintainers of these four packages did not do anything wrong, in the conventional sense — they just had a compromised credential. That single compromise propagated to seven-figure-count downstream applications inside a 15-minute window. The cost of remediation across all those applications is a real number, denominated in engineer-hours, that the ecosystem now eats every few months.


The medium-term fix is harder than any single team's hardening. It is sigstore-style cryptographic signing of tags by maintainers, with downstream verification mandatory in Composer's resolver. PHP/Composer is behind the npm and PyPI ecosystems on this. The pressure to catch up is now visible.


In the short term, every Laravel team's homework is the four hardening steps above. The work is half a day. The cost of not doing it — once an attack like this lands on a credential your runner can see — is a multi-week incident response, customer notifications, possibly regulatory disclosures, and a renewed conversation with your insurance carrier.


My Take


We have argued for years that the supply chain is the weakest link in modern web stacks. The Laravel-Lang attack is the cleanest possible demonstration that the argument is over and the defense is now your responsibility. You cannot wait for Composer's resolver to grow tag verification. You cannot wait for GitHub to ship a forced "tags are immutable" mode. You have to harden your own pipeline, this sprint, with the steps above.


For our agency clients we are running a one-day Composer Lockdown sprint this week: pin critical dependencies by SHA, mirror to a private repository, enable composer audit in CI, scope CI tokens per environment. The cost is half an engineer-day per project. The cost-of-not-doing it is the incident we just watched four hundred companies live through. The math is not close.


The deeper lesson is the one we keep relearning every few months: a credential outside the perimeter is the same as the perimeter being inside the attacker. Token hygiene is not boring — it is the single highest-leverage security work a Laravel team can do in 2026. Spend the half day. Pin the SHAs. Rotate the secrets. Move on.


Sources



Cybersecurity Back to Blog