News

The Laravel-Lang Attack Targeted Your Hosting Credentials

Muhammad SaadMay 23, 202613 min read
The Laravel-Lang Attack Targeted Your Hosting Credentials

Your Hosting Credentials Were the Target

On May 22, 2026, a supply chain attack hit the PHP ecosystem that should make every developer and hosting user sit up and pay attention. The attacker did not go after source code. They did not plant ransomware. They went after one thing: your credentials. Specifically, the API tokens, SSH keys, and environment variables that give access to hosting platforms like DigitalOcean, Heroku, Vercel, Netlify, Railway, and Fly.io.

The attack compromised over 700 versions of the popular laravel-lang localization packages — libraries with 7,800+ GitHub stars used by thousands of Laravel projects worldwide. A 5,900-line cross-platform credential stealer was injected into the packages, designed to silently harvest and exfiltrate everything from cloud provider keys to cryptocurrency wallet seeds.

The most alarming part? No malicious code was ever committed to the official repositories. The attacker exploited a little-known GitHub feature to make Packagist serve poisoned versions while the actual repo source remained clean.

This article breaks down exactly what happened, what was targeted, and what you need to do right now if any of your projects depend on Laravel-Lang packages.


What Happened: The Attack Mechanics

The Tag-From-Fork Exploit

GitHub allows git tags to point to commits in any fork of a repository — not just the main repo. The attacker exploited this by creating a fork of the Laravel-Lang repositories, adding malicious code to their fork, and then creating version tags in the official repositories that pointed to the commits in their malicious fork.

Because Packagist (PHP's package registry) resolves packages by following git tags, it served the attacker's poisoned code whenever developers ran composer install or composer update. The official repository's commit history remained completely clean, which is why the attack was so difficult to detect through normal code review.

Four Repositories, 700+ Versions

The affected packages were:

  • laravel-lang/lang — the main localization package (7,800+ stars)
  • laravel-lang/attributes — form attribute translations
  • laravel-lang/http-statuses — HTTP status code translations
  • laravel-lang/actions — action/button translations

Tags were published in rapid succession on May 22–23, 2026, with many versions appearing only seconds apart. This automated, rapid-fire approach rewrote the entire version history — meaning every historical version of these packages was poisoned, not just the latest release.

The Autoload Trojan: src/helpers.php

The malicious payload was placed in a file called src/helpers.php. This file was registered in the package's composer.json under the autoload.files directive:

{
  "autoload": {
    "files": [
      "src/helpers.php"
    ]
  }
}

This is the critical detail. Composer's autoload.files directive tells PHP to execute the listed files on every single request. There is no opt-in. There is no function call required. If the package is installed, the code runs automatically.

On the surface, helpers.php defined two innocent-looking localization helper functions. Below those functions, a self-executing block performed the real work:

  1. Fingerprinting: Generated a unique host identifier using MD5 hashes of the file path, hostname, and inode to prevent re-infection
  2. C2 Resolution: Decoded the command-and-control domain (flipboxstudio[.]info) from an integer array using array_map('chr', [...]) to evade static analysis
  3. Payload Download: Fetched the second-stage payload from flipboxstudio[.]info/payload via file_get_contents with a curl fallback, both with SSL verification disabled
  4. Cross-Platform Execution: On Linux/macOS, executed the payload in the background via exec(). On Windows, dropped a .vbs launcher and ran it silently via cscript

The staged payload was stored in sys_get_temp_dir()/.laravel_locale/ — a directory name designed to look like a legitimate Laravel cache.


The Full Credential Target List

The second-stage payload was a 5,900-line PHP credential stealer organized into 17 specialist collector modules. The scope of what it targeted is staggering. Here is the complete breakdown:

Hosting Platforms

Platform What Was Targeted
DigitalOcean API tokens, doctl config
Heroku API keys, ~/.netrc credentials
Vercel Auth tokens, project configs
Netlify Auth tokens, site configs
Railway Auth tokens
Fly.io Auth tokens, app configs

Cloud Infrastructure

Provider What Was Targeted
AWS Access keys, secret keys, session tokens, ~/.aws/credentials, EC2 instance metadata (169.254.169.254)
Google Cloud Application default credentials, access token databases, named CLI configurations
Azure Access tokens, MSAL cache, service principal profiles

Infrastructure & DevOps

Tool What Was Targeted
Kubernetes Service Account tokens (/var/run/secrets/), kubeconfig files
Docker Auth configs, docker-compose.yml files
HashiCorp Vault API tokens, sealed secrets
Helm Registry configurations

CI/CD Systems

System What Was Targeted
Jenkins master.key, credentials store
GitHub Actions Workflow tokens, secrets
GitLab CI Runner tokens, CI variables
CircleCI Auth tokens
ArgoCD Auth tokens, cluster configs

Developer Credentials

Category What Was Targeted
SSH Private keys (~/.ssh/), known hosts, SSH agent sockets
Git .gitconfig, .git-credentials, .netrc (GitHub, GitLab, Bitbucket)
Package Registries NPM/Yarn auth tokens, PyPI configs, Gem credentials, Composer auth
Environment Files All .env files (recursive scan), wp-config.php, settings.py, secrets.yaml
Shell History bash, zsh, psql, mysql, python, node REPL histories

Password Managers

Manager What Was Targeted
1Password Vault databases, local cache
Bitwarden Local vault data
LastPass Local cache, vault data
KeePass Database files (.kdbx)

Cryptocurrency Wallets

Wallet What Was Targeted
Ledger Live Wallet data, account info
Trezor Wallet data
MetaMask Browser extension vault data
Electrum Wallet files, seed data
Exodus Wallet files
Atomic Wallet Wallet files
Phantom Browser extension data
Trust Wallet Extension data
Ronin Extension data
Keplr Extension data
Solflare Extension data
Rabby Extension data

Browsers

Browser What Was Targeted
Chrome Saved passwords (including v127+ App-Bound Encryption bypass via embedded DebugChromium.exe)
Edge Saved passwords
Brave Saved passwords
Opera / Opera GX Saved passwords
Vivaldi Saved passwords
Yandex Saved passwords
Firefox Saved passwords, certificates

Communication & VPN

Service What Was Targeted
Slack Workspace tokens
Discord Auth tokens
Telegram Session data
NordVPN Saved credentials, configs
ExpressVPN Saved credentials
ProtonVPN Saved credentials
CyberGhost Saved credentials
Mullvad Account data
Surfshark Saved credentials
WireGuard Config files, private keys
OpenVPN .ovpn files, embedded credentials

Windows-Specific

Tool What Was Targeted
Windows Credential Manager All stored credentials
PuTTY Session configs, saved keys
WinSCP Saved connections, passwords
RDP .rdp files with saved credentials
Outlook Profile data, cached credentials

After collecting all of this data, the stealer encrypted everything with AES-256, exfiltrated it to flipboxstudio[.]info/exfil, and then deleted itself from disk to limit forensic evidence.


Why PHP Was the Next Target After npm

This attack did not happen in isolation. Just eleven days earlier, on May 11, 2026, the TanStack npm supply chain attack compromised over 170 npm packages and 2 PyPI packages across 404 malicious versions. That attack exploited GitHub Actions workflows using a technique called "Pwn Request" combined with cache poisoning, and it was the first documented case of a malicious npm package carrying valid SLSA provenance.

May 2026 has been a month of escalating supply chain attacks across every major package ecosystem:

  • npm/PyPI (May 11): TanStack compromise via GitHub Actions cache poisoning
  • Composer/PHP (May 22–23): Laravel-Lang compromise via tag-from-fork

The pattern is clear. Attackers are systematically working through the major package ecosystems, finding unique trust boundary violations in each one. For npm, it was GitHub Actions workflow permissions. For Composer, it was GitHub's tag-from-fork feature combined with Packagist's tag-based resolution.

The PHP ecosystem was a natural next target. Composer packages have deep autoload integration, .env files are a standard part of PHP frameworks (Laravel, Symfony), and PHP developers often run their applications on servers with direct access to production credentials. The autoload.files directive gave attackers automatic code execution without any explicit function call — something even npm's postinstall scripts cannot guarantee since many developers disable them.


How Developers Can Protect Themselves

1. Check If You Are Affected

Search your composer.lock for any of the affected packages:

# Check if you have any laravel-lang packages installed
grep -r "laravel-lang" composer.lock

# Check specific packages
composer show laravel-lang/lang 2>/dev/null
composer show laravel-lang/attributes 2>/dev/null
composer show laravel-lang/http-statuses 2>/dev/null
composer show laravel-lang/actions 2>/dev/null

If any of these packages appear in your project, assume compromise until verified otherwise.

2. Verify Package Integrity

Composer does not verify package integrity by default the same way npm ci does. But you can verify that your installed packages match expected hashes:

# Show the installed version and its reference hash
composer show --locked laravel-lang/lang

# Compare the reference hash in composer.lock against
# known-good commits on the official repository
cat composer.lock | python3 -c "
import json, sys
data = json.load(sys.stdin)
for pkg in data.get('packages', []) + data.get('packages-dev', []):
    if 'laravel-lang' in pkg.get('name', ''):
        print(f\"{pkg['name']}@{pkg['version']} ref={pkg.get('source', {}).get('reference', 'N/A')}\")
"

3. Audit Your .env Files and Environment

Check for signs of credential exfiltration:

# Look for the malware's staging directory
find /tmp -name ".laravel_locale" -type d 2>/dev/null

# Check for suspicious outbound connections in your logs
grep -r "flipboxstudio" /var/log/ 2>/dev/null

# Audit your .env files for exposure
# List all .env files in your project (they should NOT be in git)
find . -name ".env*" -not -path "./.git/*" | head -20

# Check if any .env files were accidentally committed
git log --all --diff-filter=A -- "*.env"

4. Rotate All Credentials Immediately

If you were affected, rotate everything. Not just your hosting tokens — everything the stealer targeted:

# Rotate AWS credentials
aws iam create-access-key --user-name YOUR_USER
aws iam delete-access-key --access-key-id OLD_KEY_ID --user-name YOUR_USER

# Rotate DigitalOcean tokens
doctl auth init  # Re-authenticate with a new token

# Regenerate SSH keys
ssh-keygen -t ed25519 -C "your_email@example.com" -f ~/.ssh/id_ed25519_new
# Update authorized_keys on all servers

# Rotate Laravel APP_KEY (this will invalidate all encrypted data)
php artisan key:generate

# Rotate database passwords
# Update .env with new credentials, then restart services

# Revoke and regenerate GitHub/GitLab tokens
gh auth logout && gh auth login

# Rotate Docker Hub tokens
docker logout && docker login

# Rotate Kubernetes credentials
kubectl config delete-context YOUR_CONTEXT
# Re-authenticate with your cluster

5. Lock Down Composer Going Forward

# Always commit composer.lock to version control
git add composer.lock

# Use --no-plugins and --no-scripts for initial installs
# when evaluating new packages
composer install --no-plugins --no-scripts

# Audit installed packages for known vulnerabilities
composer audit

# Pin to exact versions in production
composer update --lock

How Hosting Providers Should Respond

If you operate a hosting platform, this attack was specifically designed to compromise your users' access to your service. Here is what you should do:

Environment Isolation

  • Container isolation: Deploy customer applications in isolated containers where the application process cannot access host-level credentials or other tenants' data
  • Metadata service protection: The stealer specifically targeted cloud metadata endpoints (169.254.169.254). Ensure your infrastructure blocks or restricts access to instance metadata from customer code
  • Ephemeral credentials: Use short-lived, scoped tokens instead of long-lived API keys wherever possible

Credential Monitoring

  • Token usage anomaly detection: Monitor for unusual API token usage patterns — tokens being used from unexpected IP addresses or geographic locations
  • Bulk credential rotation tools: Provide your users with easy one-click credential rotation if they suspect compromise
  • Outbound connection monitoring: Flag and log outbound connections from customer applications to known C2 domains

Build Pipeline Security

  • Dependency scanning: Integrate supply chain scanning into your build pipelines. Tools like Socket and Aikido Security detected this attack
  • Build isolation: Run composer install in sandboxed build environments that do not have access to production credentials
  • Network restrictions during builds: Restrict outbound network access during the dependency installation phase to only known package registries

The Bigger Picture: May 2026's Supply Chain Crisis

The Laravel-Lang attack is not an isolated incident. It is part of a pattern that has made May 2026 one of the worst months for software supply chain security in history.

Consider the timeline:

  • March 2026: Aqua Security's Trivy scanner compromised via GitHub Actions
  • April 2026: Bitwarden CLI npm package compromised
  • May 11: TanStack + 160 npm/PyPI packages compromised via GitHub Actions cache poisoning (attributed to TeamPCP / "Mini Shai-Hulud")
  • May 22–23: Laravel-Lang packages compromised via tag-from-fork (700+ versions across 4 packages)

These attacks share common characteristics:

  1. Trust boundary exploitation: Each attack found a seam between trusted systems (GitHub Actions runners, git tags, Packagist resolution) and exploited the implicit trust between them
  2. Credential harvesting focus: The payloads are not crypto miners or ransomware. They are credential stealers. The attackers want persistent access to infrastructure
  3. Clean official repos: In both the TanStack and Laravel-Lang attacks, the official source code repositories remained untouched. The compromise existed in the build/distribution layer
  4. Automated scale: Hundreds of package versions were poisoned in minutes through automated tooling

The uncomfortable truth is that our package ecosystems were built on implicit trust: trust that a git tag points to the right commit, trust that a published version contains the same code as the repository, trust that autoload.files will only load legitimate helper functions.

That trust model is broken. May 2026 proved it.


What You Should Do Right Now

Here is your action checklist:

  1. Audit your composer.lock for any laravel-lang/* packages
  2. Check for the staging directory at /tmp/.laravel_locale/
  3. Search logs for any connections to flipboxstudio.info
  4. If affected, rotate all credentials — cloud keys, SSH keys, API tokens, database passwords, APP_KEY
  5. Run composer audit on all your PHP projects
  6. Enable --no-plugins --no-scripts when evaluating new Composer packages
  7. Review your CI/CD pipelines for exposed secrets and restrict outbound network access during builds
  8. Subscribe to security advisories from Packagist, Socket, and Aikido Security

Supply chain attacks are not going away. They are getting more sophisticated, more targeted, and more damaging. The Laravel-Lang attack proves that even a localization helper — a package you install and forget about — can become a vector for total credential compromise.

If you are deploying PHP applications on any hosting platform, your credentials were the target. Act accordingly.

Share this article

Muhammad Saad

Muhammad Saad

DeployBase Team

Ready to Get Started?

Join thousands of developers who trust DeployBase for their hosting needs.