Laravel Request Validation: How to Stop Using Raw $request Input in Controllers
Controllers using $request->input() or $request->all() without validation expose your app to type juggling, injection, and data corruption attacks.
The Problem
Using raw request data — $request->input(), $request->all(), $request->get(), or $_POST/$_GET — without validation lets attackers send unexpected types, overlong strings, or malicious values. Even if you have frontend validation, attackers bypass it trivially with cURL or browser dev tools. Every controller action that modifies data should validate input server-side before processing.
How to Fix
-
1
Use $request->validate() in controller methods
Replace raw input access with validated data:
// BEFORE — raw input, no validation public function store(Request $request) { Post::create($request->all()); }// AFTER — validated input public function store(Request $request) { $validated = $request->validate([ 'title' => 'required|string|max:255', 'body' => 'required|string|max:10000', 'category_id' => 'required|exists:categories,id', ]);Post::create($validated); }
-
2
Use Form Request classes for complex validation
For controllers with many validation rules, extract to a Form Request:php artisan make:request StorePostRequest// app/Http/Requests/StorePostRequest.php public function rules(): array { return [ 'title' => 'required|string|max:255', 'body' => 'required|string|max:10000', 'category_id' => 'required|exists:categories,id', 'tags' => 'array|max:10', 'tags.*' => 'string|max:50', ]; }// Controller — type-hint the Form Request public function store(StorePostRequest $request) { Post::create($request->validated()); } -
3
Validate route parameters too
Route parameters can also be manipulated:
// In RouteServiceProvider or route definition Route::get('/users/{user}', [UserController::class, 'show']) ->whereNumber('user');// Or validate in the controller public function show(string $id) { $validated = validator(['id' => $id], [ 'id' => 'required|integer|exists:users,id', ])->validate(); }
How to Verify
Search for unvalidated input usage:
grep -rn 'request->all()\|request->input(\|request->get(' app/Http/Controllers/ --include='*.php'
Every occurrence should either use ->validate(), ->validated(), or a Form Request. Run php artisan stackshield:scan --check=SS007 to verify.
Prevention
Establish a team convention: never use $request->all() or $request->input() without prior validation. Use Form Requests for all store/update actions. Add a PHPStan rule or code review checklist item to catch raw input usage.
Frequently Asked Questions
Is $request->only() safe enough?
$request->only() limits which fields are accepted but does not validate their types or values. An attacker can still send title=<script>alert(1)</script> or category_id=99999. Always validate types and constraints, not just field names.
Do I need validation for API endpoints too?
Absolutely. API endpoints are even more vulnerable because there is no browser-enforced CSRF protection or form structure. Always validate API input with the same rigor as web form input.
Related Guides
Laravel Mass Assignment Vulnerability: How to Protect Eloquent Models with $fillable and $guarded
Eloquent models without $fillable or $guarded allow attackers to set any database column through request input, including is_admin, role, or email_verified_at.
How to Prevent SQL Injection in Laravel
SQL injection vulnerabilities in raw queries and improper Eloquent usage can expose your database. Learn how to write secure queries.
Laravel XSS Prevention Guide: Blade Escaping, {!! !!} Risks & CSP Headers
Prevent cross-site scripting in Laravel. Learn when {!! !!} is safe, how to sanitize HTML input, encode output in Blade templates, and add Content Security Policy headers.
Detect This Automatically with StackShield
StackShield continuously monitors your Laravel application from the outside and alerts you when security issues are found. No installation required.
Start Free Trial