🔒 Hacked
Chapter 3

The 6 most common attack vectors in Laravel

Understanding how attackers get in is the first step to keeping them out.

This chapter covers the six most common attack vectors we’ve identified targeting Laravel applications. Each one has been used in real-world attacks - including critical CVEs discovered in 2024-2026.

Vector 1: Debug mode exploitation

The most embarrassing vulnerability is often the most common: leaving APP_DEBUG=true in production.

CVE-2024-13919 high
CVSS: 7.5

Reflected XSS in Debug Error Page

Package: laravel/framework Affected: 11.9.0 - 11.35.x

When debug mode is enabled, Laravel’s error page is vulnerable to XSS attacks. Attackers can inject malicious scripts that execute in admin browsers.

Why it’s dangerous

When APP_DEBUG=true:

The attack

  1. Attacker triggers an error (malformed input, missing route)
  2. Debug page reveals sensitive information
  3. With XSS, attacker can steal admin session cookies
  4. Full application compromise follows

Detection

Check your production environment:

Dangerous Configuration MALICIOUS CODE
// .env (WRONG - in production)
APP_ENV=production
APP_DEBUG=true  // NEVER do this!

// This combination is actively dangerous
// CVE-2024-13919 makes this exploitable

Fix

# In production .env
APP_DEBUG=false
APP_ENV=production

Vector 2: Livewire hydration smuggling

This is the most critical Laravel ecosystem vulnerability discovered in recent years.

CVE-2025-54068 critical
CVSS: 9.8

Remote Code Execution via Hydration Smuggling

Package: livewire/livewire Affected: 3.0.0 - 3.6.3

Unauthenticated attackers can achieve RCE by manipulating Livewire’s JSON payload during the hydration process. No authentication required.

💀

CVSS 9.8 - Maximum Severity

This vulnerability allows unauthenticated remote code execution. If you’re running Livewire 3.0-3.6.3, you are vulnerable RIGHT NOW. There is no workaround except updating.

How it works

Livewire components serialize their state to JSON for client-server communication. The vulnerability exists in how this data is deserialized (hydrated):

  1. Attacker crafts malicious JSON payload
  2. Payload contains serialized PHP objects
  3. During hydration, these objects are unserialized
  4. Gadget chains execute arbitrary code

Attack indicators

Watch for these in your logs:

Fix

composer require livewire/livewire:^3.6.4

Vector 3: Environment variable injection

A subtle but devastating attack that exploits PHP’s register_argc_argv setting.

CVE-2024-52301 high
CVSS: 8.7

Environment Injection via Query String

Package: laravel/framework Affected: Multiple versions (see below)

When register_argc_argv=On in PHP, attackers can manipulate Laravel’s environment variables through URL query strings.

The Attack

When register_argc_argv is enabled (default on many systems):

https://yoursite.com/?APP_ENV=local&APP_DEBUG=true

This query string can override your environment variables, enabling debug mode or changing the application environment.

Affected versions

Laravel VersionPatched Version
6.x6.20.45
7.x7.30.7
8.x8.83.28
9.x9.52.17
10.x10.48.23
11.x11.31.0

Detection

Check if vulnerable
// Check PHP configuration
if (ini_get('register_argc_argv') === '1') {
  echo "VULNERABLE: register_argc_argv is enabled";
}

Fix

Two options:

  1. Update Laravel to patched versions
  2. Disable in php.ini:
register_argc_argv = Off

Vector 4: Laravel pulse RCE

If you use Laravel Pulse for monitoring, this one’s for you.

CVE-2024-55661 critical
CVSS: 9.1

RCE via Public remember() Method

Package: laravel/pulse Affected: < 1.3.1

The remember() method in Pulse’s Livewire trait was publicly accessible, allowing cache poisoning and remote code execution.

The attack

  1. Attacker accesses Pulse dashboard (often unprotected)
  2. Exploits public remember() method
  3. Injects malicious cached data
  4. Cached data executes on subsequent requests

Fix

composer require laravel/pulse:^1.3.1

Also ensure Pulse access is restricted:

Restrict Pulse Access
// In PulseServiceProvider or Gate
Gate::define('viewPulse', function ($user) {
  return $user->isAdmin();
});

Vector 5: File upload exploitation

The attack vector we experienced firsthand. Twice.

Why Laravel apps are vulnerable

Laravel makes file uploads easy - sometimes too easy:

Vulnerable Upload Code MALICIOUS CODE
// DANGEROUS: No extension validation
public function upload(Request $request)
{
  $request->validate([
      'file' => 'required|file|max:2048|mimes:jpg,png'
  ]);

  // mimes only checks MIME type, not extension!
  $path = $request->file('file')->store('public/uploads');

}

The mimes rule checks the file’s MIME type, which can be forged. An attacker can upload shell.php with a forged image/jpeg MIME type.

The safe way

Secure Upload Code
public function upload(Request $request)
{
  $request->validate([
      'file' => [
          'required',
          'file',
          'max:2048',
          // Check actual extension
          function ($attribute, $value, $fail) {
              $ext = strtolower($value->getClientOriginalExtension());
              $allowed = ['jpg', 'jpeg', 'png', 'gif', 'pdf'];
              if (!in_array($ext, $allowed)) {
                  $fail('Invalid file type.');
              }
              // Also block PHP
              if (in_array($ext, ['php', 'phtml', 'php3', 'php4', 'php5', 'phar'])) {
                  $fail('PHP files are not allowed.');
              }
          },
      ],
  ]);

  // Generate safe filename
  $safeName = Str::uuid() . '.' . $request->file('file')
      ->getClientOriginalExtension();

  $path = $request->file('file')->storeAs('uploads', $safeName);

}

Critical: Block PHP in upload directories

Add .htaccess to prevent PHP execution:

# storage/app/public/.htaccess
<FilesMatch "\.php$">
    Deny from all
</FilesMatch>

# Or completely disable PHP
php_flag engine off

Vector 6: APP_KEY Deserialization

If your APP_KEY leaks, it’s game over.

Why APP_KEY matters

Laravel uses APP_KEY to:

The attack chain

  1. Attacker obtains APP_KEY (from exposed .env, git history, error pages)
  2. Crafts malicious serialized PHP object
  3. Encrypts it with the stolen key
  4. Sends encrypted payload as cookie or input
  5. Laravel decrypts and unserializes it
  6. Gadget chain executes arbitrary code
💀

APP_KEY Compromise = Full RCE

If your APP_KEY is exposed, attackers can execute arbitrary code on your server using known gadget chains (phpggc). There is no mitigation except rotating the key.

Attack pattern detection

Malicious Pattern MALICIOUS CODE
// Attacker uses decrypt() with user input
$payload = decrypt($_POST['data']);  // DANGEROUS!

// Or unserializes decrypted data
$data = unserialize(decrypt($input)); // CRITICAL!

Prevention

  1. Never commit .env to git

    # .gitignore
    .env
    .env.backup
    .env.production
  2. Check git history for leaks

    git log -p --all -S 'APP_KEY'
  3. Rotate keys if compromised

    php artisan key:generate
    # Then invalidate all sessions
  4. Never pass encrypted user input to unserialize()


Summary: The 6 Vectors

#VectorCVESeverityKey Defense
1Debug ModeCVE-2024-13919HIGHAPP_DEBUG=false in production
2Livewire HydrationCVE-2025-54068CRITICALUpdate to Livewire 3.6.4+
3Environment InjectionCVE-2024-52301HIGHregister_argc_argv=Off
4Pulse RCECVE-2024-55661CRITICALUpdate Pulse, restrict access
5File UploadN/AHIGHValidate extensions, block PHP
6APP_KEY LeakN/ACRITICALNever expose, rotate if leaked
🚨

Are You Vulnerable?

Right now, ask yourself:

  • Is my Livewire version 3.6.4 or higher?
  • Is APP_DEBUG set to false in production?
  • Is my APP_KEY safe and uncompromised?
  • Can PHP files execute in my upload directories?

If you answered “no” or “I don’t know” to any of these, you’re at risk.


Next: Chapter 4 - The 87 Signatures: A Deep Dive into PHP Malware →

In the next chapter, we’ll examine the specific malware patterns attackers use - the 87 signatures our research identified targeting PHP and Laravel applications.