Unguarded Models Analyzer
| Analyzer ID | Category | Severity | Time To Fix |
|---|---|---|---|
unguarded-models | 🛡️ Security | High | 20 minutes |
What This Checks
- Scans your codebase for
Model::unguard()/Eloquent::unguard()static calls that disable Laravel’s mass-assignment protection. - Ensures every
unguard()is immediately followed by a correspondingModel::reguard(). - Flags lingering unguarded sections in controllers, services, jobs, models, and seeders with severity mapped to the file’s context.
- Ignores vendor code and custom methods so only your application’s misuse is reported.
Why It Matters
- Mass-assignment vulnerabilities: Unguarded models let attackers set attributes like
is_adminorbalancethrough crafted requests. - Invisible regressions: Once added,
Model::unguard()quietly affects every subsequentModel::create()call untilreguard()is executed. - Code readability: Force-filling explicit fields (
forceFill/forceCreate) makes intent obvious and safer for reviewers. - Compliance: Many security reviews (SOC2, ISO 27001) require demonstrating that sensitive models remain protected by default.
How to Fix
Quick Fix (5 minutes)
- Remove the blanket
Model::unguard()call when possible and rely on$fillable/$guardedproperties.
php
// ❌ Before: global unguard in a controller
Model::unguard();
User::create($request->all());
// ✅ After: validate + mass assign only what is allowed
$user = User::create($request->validated());- If you must import raw payloads, limit the scope and re-guard immediately:
php
Model::unguard();
User::forceCreate($payload);
Model::reguard();Proper Fix (20 minutes)
- Audit every unguard: search for
::unguardand confirm why it exists; remove it entirely for HTTP-facing code. - Use
$fillable/$guardedon each model so only trusted attributes can be mass-assigned. - Choose force-fill when necessary:php
$user->forceFill([ 'name' => $payload['name'], 'email' => $payload['email'], ])->save(); - Wrap imports: if a seeder or migration needs unguarded writes, wrap the block and call
Model::reguard()in afinallyclause to guarantee re-guarding even on exceptions. - Add tests around your import/service layers to ensure no requests can set privileged flags without authorization.
References
Related Analyzers
- Mass Assignment Vulnerabilities Analyzer — detects missing
$fillable/$guardeddefinitions. - Fillable Foreign Key Analyzer — ensures relationship IDs aren't mass assignable.
- Stable Dependencies Analyzer — keeps your vendor libraries on predictable, secure releases.