Your Laravel APP_KEY Is Probably on GitHub. Here Is Why That Means RCE.
GitGuardian found 260,000 exposed Laravel APP_KEYs on GitHub. With the right key, attackers can achieve remote code execution on your server in seconds. Here is how the attack works and how to protect yourself.
In a joint research effort, GitGuardian and Synacktiv analyzed publicly exposed Laravel APP_KEY values on GitHub and found the results alarming: 260,000 exposed keys, 400 validated as functional, and confirmed remote code execution on production Laravel applications.
Your APP_KEY is the single most dangerous secret in your Laravel application. Unlike a database password (which requires network access to the database), a leaked APP_KEY can be exploited remotely by anyone who can send an HTTP request to your application.
What is the APP_KEY and why does it matter?
The APP_KEY is a 32-byte symmetric encryption key defined in your .env file:
APP_KEY=base64:wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY=
Laravel uses it to encrypt:
- Session data — including authentication tokens
- Cookies — including the session cookie itself
- Cache values — anything stored via the Cache facade
- Any data processed by
Crypt::encrypt()
If an attacker has your APP_KEY, they can decrypt all of the above. But the real danger is worse than decryption.
How APP_KEY leads to remote code execution
Laravel's decrypt() function does two things:
- Decrypts the data using the
APP_KEY - Automatically deserializes the decrypted data via PHP's
unserialize()
Step 2 is the problem. PHP deserialization is a well-known attack vector. If an attacker can control the input to unserialize(), they can trigger "gadget chains" — sequences of existing PHP class methods that execute during deserialization and ultimately run arbitrary commands.
The attack in practice
- Attacker finds your
APP_KEY(from GitHub, exposed.env, or other leaks) - Attacker uses phpggc to generate a malicious PHP object serialization payload — phpggc catalogs 22+ RCE gadget chains across Laravel versions 5.1 through 12
- Attacker encrypts the payload using your
APP_KEY - Attacker sends the encrypted payload to your application (via a cookie, for example)
- Laravel decrypts the payload and calls
unserialize() - The gadget chain executes, giving the attacker shell access to your server
The entire attack can be automated and executed in seconds.
# Example using phpggc (for security research only)
phpggc Laravel/RCE10 system "id" -b | \
php -r '$key = "YOUR_APP_KEY"; echo encrypt(file_get_contents("php://stdin"), $key);'
Known CVEs
This attack vector has been documented in multiple CVEs:
- CVE-2018-15133 — the original Laravel RCE via APP_KEY
- CVE-2024-55555 — additional deserialization vectors
- CVE-2024-55556 — further gadget chain exploits
The scale of the problem
GitGuardian's research paints a clear picture:
| Metric | Number |
|---|---|
| APP_KEYs exposed on GitHub since 2018 | 260,000 |
| Unique keys identified | 10,000+ |
| APP_KEY + APP_URL pairs exposed | 28,000 |
| Keys validated as still functional | 400 |
| Applications confirmed vulnerable to trivial RCE | 120 |
| Production RCE confirmed and reported | 4 |
63% of exposures came from committed .env files. The remaining 35%+ came from configuration files, documentation, scripts, and other sources.
Perhaps most concerning: 50 keys that developers had deleted from their repositories were still valid in production. Deleting a file from a git repository does not remove it from the history. The key is still accessible to anyone who clones the repo.
Co-leaked secrets
When an APP_KEY is exposed, it rarely travels alone. GitGuardian found that 35% of exposures included other critical secrets:
- Database credentials
- AWS/cloud provider tokens
- Payment gateway keys (Stripe, PayPal)
- AI service API keys
- SMTP credentials
A single committed .env file can compromise your entire infrastructure.
How to check if your APP_KEY is exposed
1. Search your git history
# Check if .env was ever committed
git log --all --diff-filter=A -- .env
# Search for APP_KEY in any committed file
git log --all -p -S "APP_KEY=base64:" --source
# Check if .env is in .gitignore
grep -n ".env" .gitignore
2. Check your live application
# Is your .env file publicly accessible?
curl -s -o /dev/null -w "%{http_code}" https://yourdomain.com/.env
# A 200 response means your .env (and APP_KEY) is exposed
# You want 403 or 404
3. Use automated scanning
- GitHub Secret Scanning — enable in your repository settings (free for public repos)
- GitGuardian — monitors for exposed secrets across GitHub
- StackShield — checks for
.envfile exposure on every scan
Remediation
If your APP_KEY is exposed
Step 1: Generate a new key immediately
php artisan key:generate
Step 2: Deploy the new key to all environments
Update your .env file on every server. If you use environment variables via your hosting provider (Forge, Vapor, etc.), update it there.
Step 3: Understand the impact of rotation
Rotating your APP_KEY invalidates:
- All active user sessions (users will be logged out)
- All encrypted cookies
- All data encrypted with
Crypt::encrypt()using the old key - Cached values that were encrypted
If you store encrypted data at rest (e.g., encrypted database columns), you need to re-encrypt that data with the new key before rotating. Laravel does not handle this automatically.
Step 4: Remove the key from git history
Simply deleting .env from the repo is not enough. The key persists in git history.
# Using BFG Repo-Cleaner (recommended)
bfg --delete-files .env
git reflog expire --expire=now --all && git gc --prune=now --aggressive
# Force push to overwrite remote history
git push --force
Step 5: Rotate all co-leaked secrets
If your .env was committed, assume every secret in it is compromised. Rotate database passwords, API keys, SMTP credentials, and all third-party service tokens.
Preventing future exposure
1. Ensure .env is in .gitignore
Every Laravel project includes .env in .gitignore by default, but this can be accidentally removed or overridden:
# Verify .env is ignored
echo ".env" >> .gitignore
git rm --cached .env 2>/dev/null # Remove if tracked
2. Use environment variables instead of .env files in production
Many hosting platforms (Forge, Vapor, Railway, Fly.io) let you set environment variables directly, so you never need a .env file on the server.
3. Enable GitHub secret scanning
Go to your repository Settings > Code security and analysis > Secret scanning and enable it. GitHub will alert you if secrets are pushed.
4. Add a pre-commit hook
# .git/hooks/pre-commit
#!/bin/sh
if git diff --cached --name-only | grep -q "\.env$"; then
echo "ERROR: Attempting to commit .env file"
exit 1
fi
5. Monitor your application externally
External monitoring catches .env exposure in production even when your git hygiene is perfect. Server misconfigurations, deployment errors, and web server changes can expose .env files that were never in your repository.
The lesson
Your APP_KEY is not just an encryption key. It is a remote code execution credential. Treat it with the same seriousness as your SSH private key or database root password. If it has ever been in a git repository — even briefly, even in a branch that was deleted — assume it is compromised and rotate it today.
Frequently Asked Questions
What is the Laravel APP_KEY used for?
The APP_KEY is a 32-byte symmetric encryption key that Laravel uses for encrypting cookies, session data, cache values, and any data processed by the Crypt facade. It is the single most sensitive value in your .env file. If an attacker obtains it, they can decrypt any data your application encrypted and, more critically, craft payloads that achieve remote code execution through PHP deserialization.
How does a leaked APP_KEY lead to remote code execution?
Laravel's decrypt() function automatically deserializes decrypted data. An attacker with your APP_KEY can encrypt a malicious PHP object (a "gadget chain") and send it to your application via a cookie or other encrypted input. When Laravel decrypts and deserializes the payload, the gadget chain executes arbitrary commands on your server. The phpggc tool catalogs 22+ RCE gadget chains across Laravel versions 5.1 through 12.
How do I check if my Laravel APP_KEY has been leaked?
Search GitHub for your APP_KEY value (or a portion of it). Check your git history for any commits that included your .env file: git log --all --diff-filter=A -- .env. Use GitGuardian, GitHub secret scanning, or similar tools to monitor for exposed secrets. Also check if your .env file is publicly accessible by visiting yourdomain.com/.env in a browser.
What should I do if my Laravel APP_KEY is exposed?
Immediately generate a new APP_KEY with php artisan key:generate. Deploy the new key to all environments. Invalidate all existing sessions by clearing the session store. Re-encrypt any data that was encrypted with the old key. Remove the exposed key from your git history using git filter-branch or BFG Repo-Cleaner. Do not just delete the .env file from the repository — the key remains in git history.
Does rotating my APP_KEY break anything?
Yes, rotating the APP_KEY invalidates all existing encrypted data: sessions, cookies, cached values, and any data stored using the Crypt facade. Users will be logged out, and any encrypted-at-rest data becomes unreadable. Plan for this by re-encrypting stored data before rotating, or accept the session invalidation as a necessary security measure.
Related Articles
Laravel Debug Mode in Production: Why It's Dangerous and How to Fix It
Debug mode in production exposes stack traces, database credentials, environment variables, and internal paths. Learn exactly what it reveals, how attackers use it, and how to make sure it never reaches production.
SecurityOWASP Top 10 for Laravel: A Practical Guide
A hands-on mapping of every OWASP Top 10 (2021) category to specific Laravel vulnerabilities, with code examples of what goes wrong and how to fix it.
SecurityIs Your Laravel .env File Exposed? How to Check and Fix It
Your .env file contains database credentials, API keys, and encryption secrets. If it's accessible from the web, attackers already have everything they need. Here's how to check and fix it.
Compare StackShield
Security Checklists
Laravel Production Deployment Security Checklist
A comprehensive security checklist for deploying Laravel applications to production. Covers environment config, server hardening, access control, and monitoring.
20 itemsLaravel API Security Checklist
Secure your Laravel API endpoints against common vulnerabilities. Covers authentication, input validation, rate limiting, and response security.