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:
- Token storage on the client: API tokens stored in localStorage are accessible to any JavaScript running on the page (XSS risk). Sanctum's recommended pattern for SPAs uses HttpOnly cookies, not localStorage tokens.
- Token expiry enforcement: We verify that Sanctum tokens have an expiration configured and that expired tokens are rejected at the middleware level.
- Token scope restrictions: Sanctum supports ability-based token scopes. We test whether restricted tokens can access endpoints they are not scoped for.
- Logout and token revocation: We verify that logout invalidates the server-side token record, not just the client-side cookie or localStorage entry.
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.
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 PentestFrequently 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