# 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.

**Severity:** medium | **Category:** Application Security

---

## The Issue

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.

## Steps 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();
}

## Verification

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.

