1. Mass assignment via Eloquent model configuration

Laravel's Eloquent ORM allows mass assignment through the create() and update() methods when models define a $fillable whitelist or an empty $guarded array. The most common critical finding is a model with protected $guarded = [] combined with a controller that passes the full request payload:

// VULNERABLE controller and model combination
class UserController extends Controller
{
    public function update(Request $request, $id)
    {
        // Passes everything from the HTTP request to Eloquent
        User::find($id)->update($request->all());
        return response()->json(['status' => 'updated']);
    }
}

// Model with no fillable restrictions
class User extends Model
{
    protected $guarded = []; // Any column can be written
}

With this pattern, an attacker submitting {"is_admin": true, "kyc_level": 3} alongside a legitimate profile update writes both fields directly to the database. We test every controller action that calls create() or update() with request data.

2. Laravel Sanctum and Passport token security

Laravel Sanctum is the default API authentication layer for modern Laravel applications. We test four areas of Sanctum security:

3. APP_DEBUG mode and .env exposure

We check for APP_DEBUG=true in production by triggering deliberate error conditions (invalid route parameters, malformed JSON, missing required fields) and examining the response body. We also test whether the .env file is accessible via the web server root at /.env. This file contains the APP_KEY (which can be used to forge encrypted session cookies), the database password, the mail credentials, and every third-party API key the application uses.

4. Artisan command injection through exposed routes

In some development setups, Laravel applications expose administrative Artisan commands through web routes for convenience. We identify any route that executes shell commands, invokes Artisan commands, or passes user input to PHP's exec(), shell_exec(), or system() functions. These are high-severity findings because they grant Remote Code Execution on the server.

5. Laravel queue worker and job deserialization

Laravel uses serialized PHP objects to represent queued jobs. If your queue backend (Redis, database) is accessible to an attacker and the application processes untrusted serialized job data, PHP Object Injection can be used to execute arbitrary code through a deserialization gadget chain. We audit your queue configuration and the reachability of your queue storage backend from untrusted network segments.

Real finding from a Laravel engagement

Mass assignment escalation to admin via empty $guarded

During a security assessment of a Nigerian logistics platform, we identified an account settings endpoint that updated the user record using $request->all(). The User model had $guarded = []. By including "is_admin": true in the update payload, we upgraded our test account to administrator, gaining full access to the admin panel including driver assignment, pricing configuration, and customer PII export. Fix priority: critical. Remediated by adding an explicit $fillable whitelist to the User model and validating request fields against that list in the controller.

Running a Laravel application in production? Book a practitioner-led security assessment.

Book a Laravel Pentest

Frequently asked questions

Is Laravel's Eloquent ORM safe from SQL injection?

Eloquent ORM parameterizes standard query builder calls, but using whereRaw(), DB::statement(), or string formatting inside query methods bypasses this protection. We test every raw query path in your application.

What are the security risks of Laravel Sanctum and Passport?

Sanctum uses signed cookies for SPA authentication and API tokens for mobile. The main risks are tokens stored in localStorage (XSS exposure), missing token expiry enforcement, and API token scopes that grant broader access than intended. Passport has additional risks around its OAuth server configuration.

How do you find mass assignment vulnerabilities in Laravel?

We look for Eloquent models where the $guarded array is empty or set to an empty array, combined with controller methods that pass $request->all() directly to Model::create() or Model::update(). This pattern allows client-submitted JSON fields to overwrite any database column.

Is APP_DEBUG=true dangerous in production Laravel apps?

Yes. When APP_DEBUG is true, Laravel renders detailed error pages containing: the full stack trace, every local variable value at each frame, and all registered environment variables including the database password, APP_KEY, and third-party API credentials.

Related reading

Blog: Securing Laravel APIs · Django penetration testing · BOLA in payment APIs

Services: Penetration testing · API security testing