Laravel is a powerful, open-source PHP web framework designed to streamline web application development. It offers robust built-in features, including comprehensive authentication systems, database management, and routing. With its widespread adoption across millions of websites globally, Laravel's popularity makes it a prime target for security vulnerabilities and secret exposure.

The APP_KEY is a randomly generated 32-byte symmetric encryption key that Laravel uses internally for critical security operations, including data encryption/decryption (cookies, session data), and secure generation of encrypted password reset tokens. This key is automatically utilized by Laravel's encrypt() and decrypt() functions without requiring explicit developer intervention. However, Laravel's current implementation introduces a significant security vulnerability: the decrypt() function automatically deserializes decrypted data, creating a potential remote code execution vector.

In PHP environments, successful exploitation of deserialization vulnerabilities typically enables attackers to achieve arbitrary code execution on the target system. Specifically in Laravel applications, if attackers obtain the APP_KEY and can invoke the decrypt() function with a maliciously crafted payload, they can achieve remote code execution on the Laravel web server.

This attack scenario is far from being theoretical but poses a real threat for several critical reasons.

First, Laravel's codebase contains numerous well-documented PHP gadget chains that can be combined together to achieve arbitrary command execution during the `unserialize()` process. These chains are catalogued and readily available in tools, such as phpggc (PHP Generic Gadget Chains), up to Laravel v12.

$ ./phpggc -l laravel

Gadget Chains
-------------

NAME             VERSION                  TYPE                  VECTOR        I    
Laravel/FD1      *                        File delete           __destruct    *    
Laravel/RCE1     5.4.27                   RCE: Function Call    __destruct         
Laravel/RCE2     5.4.0 <= 8.6.9+          RCE: Function Call    __destruct         
Laravel/RCE3     5.5.0 <= 5.8.35          RCE: Function Call    __destruct    *    
Laravel/RCE4     5.4.0 <= 8.6.9+          RCE: Function Call    __destruct         
Laravel/RCE5     5.8.30                   RCE: PHP Code         __destruct    *    
Laravel/RCE6     5.5.* <= 5.8.35          RCE: PHP Code         __destruct    *    
Laravel/RCE7     ? <= 8.16.1              RCE: Function Call    __destruct    *    
Laravel/RCE8     7.0.0 <= 8.6.9+          RCE: Function Call    __destruct    *    
Laravel/RCE9     5.4.0 <= 9.1.8+          RCE: Function Call    __destruct         
Laravel/RCE10    5.6.0 <= 9.1.8+          RCE: Function Call    __toString         
Laravel/RCE11    5.4.0 <= 9.1.8+          RCE: Function Call    __destruct         
Laravel/RCE12    5.8.35, 7.0.0, 9.3.10    RCE: Function Call    __destruct    *    
Laravel/RCE13    5.3.0 <= 9.5.1+          RCE: Function Call    __destruct    *    
Laravel/RCE14    5.3.0 <= 9.5.1+          RCE: Function Call    __destruct         
Laravel/RCE15    5.5.0 <= v9.5.1+         RCE: Function Call    __destruct         
Laravel/RCE16    5.6.0 <= v9.5.1+         RCE: Function Call    __destruct         
Laravel/RCE17    10.31.0                  RCE: Function Call    __destruct         
Laravel/RCE18    10.31.0                  RCE: PHP Code         __destruct    *    
Laravel/RCE19    10.34                    RCE: Command          __destruct         
Laravel/RCE20    5.6 <= 10.x              RCE: Function Call    __destruct         
Laravel/RCE21    5.1.*                    RCE: Function Call    __destruct         
Laravel/RCE22    v10.0.0 <= v11.34.2+     RCE: Function Call    __destruct

phpgcc Laravel gadgets and vulnerable versions

Second, the security research community recognizes that APP_KEY compromise becomes critically dangerous when combined with application-level vulnerabilities, as demonstrated by recent discoveries from Synacktiv researchers in 2024, including vulnerabilities in Invoice Ninja (CVE-2024-55555) and Snipe-IT (CVE-2024-48987). These vulnerabilities enable attackers to achieve remote code execution on affected systems.

Finally, trivial remote code execution attacks become possible when Laravel serializes and encrypts cookies using the APP_KEY. This vulnerability was first documented with CVE-2018-15133, which affected Laravel versions prior to 5.6.30. However, this attack vector persists in newer Laravel versions when developers explicitly configure session serialization in cookies using the SESSION_DRIVER=cookie setting, as demonstrated by CVE-2024-55556.

From Theory to Practice

My interest in Laravel APP_KEY vulnerabilities began in November 2024 at the GreHack Conference, where friends from Synacktiv delivered an in-depth presentation on these security issues. Rémi and Mickaël presented their comprehensive research findings on Laravel cryptographic vulnerabilities.

GreHack 2024 - Laravel - Deep dive in Laravel encryption

Using Shodan, a specialized search engine for internet-facing devices, they uncovered 650,000 Laravel instances and retrieved the corresponding session cookies, using the Set-Cookie: XSRF-TOKEN= query. Through systematic reconnaissance using Google and GitHub dorks, they collected publicly exposed APP_KEY. Utilizing their custom Laravel crypto killer tool, they successfully validated over 6,000 APP_KEY and identified that more than 400 Laravel applications could be trivially compromised through remote code execution attacks.

$ python laravel_crypto_killer.py check --url https://www.example.org --key base64:SGVsbG8gZnJvbSBydW1wcyBhdCBTU1RJQyAyMDI1ISE=
 ___                                _       ___                    _             __       _   _              
(O O)                              (_ )    ( O_`\                 ( )_          ( O)    _(_ )(_ )            
 | |      _ _ _ __  _ _ _   _   __  | |    | ( (_)_ __ _   _ _ _  | ,_)  _      |  |/')(_)| | | |   __  _ __ 
 | |    /'_` ( '__/'_` ( ) ( )/'__`\| |    | |  _( '__( ) ( ( '_`\| |  /'_`\    |  , < | || | | | /'__`( '__)
<  |__ ( (_| | | ( (_| | \_/ (  ___/| |   <  (_( | |  | (_) | (_) | |_( (_) )  <  | \`\| || | | |(  ___| |   
<_____/`\__,_(_) `\__,_`\___/`\____(___)  <_____/(_)  `\__, | ,__/`\__`\___/'  <__)  (_(_(___(___`\____(_)   
                                                     ( )_| | |                                             
                                                     `\___/(_)    

[+] Cookies decrypted:
    * XSRF-TOKEN
 (contains serialized data)
s:81:"a4d0e5947d190e3e2c1a3abfcdcfe610176b974c|y5LcI3hGj46KDBA8NwBlmMigS3YIpz6wi6hUeajI";
    * sstic_session
 (contains serialized data)
s:81:"c487b436096b788089efd1cdf18b9f537536601d|8HmruhPXM8Jh9GfwaJowUUbIWhLXA2YzMlNpV8aZ";

Laravel crypto killer output with serialized data

The validation process is straightforward: first, retrieve the session cookies from the target application, then attempt to decrypt them locally using the compromised APP_KEY. If decryption succeeds, verify that the resulting plaintext contains serialized PHP objects, confirming the vulnerability.

Following their presentation, I immediately approached them to discuss potential collaboration. I explained that at GitGuardian, we have been monitoring GitHub activity in real-time since 2018, and would likely have access to numerous exposed APP_KEYs that could support their research. Our collaboration started right away, and we defined patterns that allowed me to crunch data and finally extract 260,000 APP_KEY. This extended dataset helped Rémi and Mickaël to extend their result to 600 trivially compromised Laravel applications, but our analysis was just beginning to reveal the full scope of the problem.

From Detection to Validation

Our collaboration with Synacktiv not only expanded the scale of vulnerable applications but also revealed new attack vectors. During the APP_KEY extraction process, it became apparent that many developers were inadvertently exposing APP_URL alongside their APP_KEY. The APP_URL configuration defines the application's base URL, which Laravel uses to generate absolute links and asset URLs. Having both the APP_URL and APP_KEY creates a powerful attack vector: attackers can directly access the target application, retrieve session cookies, and attempt to decrypt them using the exposed key.

Since 2018, approximately 28,000 APP_KEY and APP_URL pairs have been exposed on GitHub. Of these, roughly 10% remain valid, with 120 applications currently vulnerable to trivial remote code execution attacks. More concerning, 50 of these compromised APP_KEYs have since been deleted from GitHub repositories; the developers discovered their exposure but chose to simply remove the commits rather than properly rotating the compromised secrets.

Laravel applications vulnerable to RCE since 2018

From APP_KEY to more secrets

These troubling security practices raised a critical question: if developers are mishandling APP_KEYs so carelessly, what other secrets might be at risk? This concern prompted further investigation into APP_KEY exposures to determine whether they correlate with other sensitive secrets leaks.

Analysis of filenames containing APP_KEYs revealed that 63% originate from .env files or variants such as .env.production. This indicates that exposures typically occur in configuration files containing diverse application secrets, not exclusively Laravel credentials.

Comprehensive analysis reinforces this observation: over one-third of APP_KEY disclosures are coupled with additional secret exposures. These secrets rarely exist in isolation, and their exposure extends far beyond Laravel application compromise to potentially affect entire infrastructure environments.

When analyzing valid credentials, the most common co-leaked secrets include database credentials (MongoDB, MySQL, PostgreSQL..) and cloud storage tokens (Digital Ocean Spaces, Dropbox, AWS S3…). Additional exposed credentials frequently include e-commerce platforms (Stripe, PayPal, Square, WePay…), customer support systems (JIRA, Zendesk, HubSpot…), and increasingly common AI service tokens (OpenAI, Hugging Face…).

The attack combinations are limitless. For instance, one case involved an invalid APP_KEY/APP_URL pair alongside valid Digital Ocean Spaces credentials, potentially enabling unauthorized access to server data belonging to a medical school's customer base. Similarly, a MySQL credential leaked in 2020 was subsequently deleted from the repository but remained valid in production, as evidenced by the "db-prod" hostname designation.

From Research to Product

These research findings highlighted the need for a new Laravel APP_KEY secret detector. Working closely with GitGuardian's development team, we translated our research methodologies into a production-ready secret detector and checker. Since early June 2025, GitGuardian has integrated APP_KEY detection and validation capabilities directly into its product. This implementation has proven highly effective, identifying more than 10,000 unique APP_KEYs across GitHub.

Among these discoveries, approximately 1,300 instances contained both APP_KEY and APP_URL pairs, creating the ideal conditions for exploitation validation. Through automated testing of these exposed credentials, GitGuardian successfully validated 400 APP_KEY as functional, with 4 confirmed cases of trivial remote code execution vulnerabilities in production Laravel applications. These findings demonstrate the critical importance of continuous secret monitoring and the alarming prevalence of exploitable Laravel misconfigurations in real-world deployments.This research underscores the power of collaborative security research: by combining Synacktiv's expertise with GitGuardian's monitoring infrastructure, we transformed a focused study into a comprehensive vulnerability assessment affecting thousands of applications. At GitGuardian, we remain committed to supporting similar joint investigations that protect the broader ecosystem. We welcome researchers interested in similar collaborative investigations.A companion technical article focusing on Laravel APP_KEY leakage vulnerabilities and large-scale analysis of exposed applications is published on the Synacktiv blog. Follow the link to know more!

FAQ

What is Laravel APP_KEY and why is it critical?

Laravel APP_KEY is a randomly generated 32-byte symmetric encryption key that Laravel uses internally for critical security operations, including data encryption/decryption (cookies, session data), and secure generation of encrypted password reset tokens. This key is automatically utilized by Laravel's encrypt() and decrypt() functions. However, Laravel's current implementation introduces a significant security vulnerability: the decrypt() function automatically deserializes decrypted data, creating a potential remote code execution vector.

How can attackers exploit exposed Laravel APP_KEYs?

If attackers obtain the APP_KEY and can invoke the decrypt() function with a maliciously crafted payload, they can achieve remote code execution on the Laravel web server. This is possible because Laravel's codebase contains numerous well-documented PHP gadget chains that can be combined to achieve arbitrary command execution during the unserialize() process. These chains are catalogued and readily available in tools like phpggc (PHP Generic Gadget Chains).

What makes APP_KEY exposure particularly dangerous when combined with APP_URL?

Having both the APP_URL and APP_KEY creates a powerful attack vector: attackers can directly access the target application, retrieve session cookies, and attempt to decrypt them using the exposed key. Since 2018, approximately 28,000 APP_KEY and APP_URL pairs have been exposed on GitHub. Of these, roughly 10% remain valid, with 120 applications currently vulnerable to trivial remote code execution attacks.

Do APP_KEY exposures typically occur in isolation?

No. Analysis shows that 63% of APP_KEY exposures originate from .env files or variants such as .env.production, which typically contain diverse application secrets. Over one-third of APP_KEY disclosures are coupled with additional secret exposures, including database credentials (MongoDB, MySQL, PostgreSQL), cloud storage tokens (Digital Ocean Spaces, Dropbox, AWS S3), e-commerce platforms (Stripe, PayPal), and AI service tokens (OpenAI, Hugging Face).

What is the scale of Laravel APP_KEY exposure on GitHub?

Research conducted in collaboration with Synacktiv revealed that approximately 260,000 APP_KEYs have been exposed on GitHub since 2018. GitGuardian's monitoring has identified more than 10,000 unique APP_KEYs across GitHub, with approximately 1,300 instances containing both APP_KEY and APP_URL pairs. Through automated testing, GitGuardian successfully validated 400 APP_KEYs as functional, with 4 confirmed cases of trivial remote code execution vulnerabilities in production Laravel applications.

How should developers properly handle compromised APP_KEYs?

Developers should never simply delete exposed APP_KEYs from repositories without proper rotation. Research shows that 50 compromised APP_KEYs were deleted from GitHub repositories but remained valid in production systems. The proper response involves: immediately rotating the compromised APP_KEY, updating all production systems with the new key, and implementing continuous secret monitoring to prevent future exposures.