# Security Best Practices ## Mass Assignment Protection Every model must define `$fillable` (whitelist) or `$guarded` (blacklist). Incorrect: ```php class User extends Model { protected $guarded = []; // All fields are mass assignable } ``` Correct: ```php class User extends Model { protected $fillable = [ 'name', 'email', 'password', ]; } ``` Never use `$guarded = []` on models that accept user input. ## Authorize Every Action Use policies or gates in controllers. Never skip authorization. Incorrect: ```php public function update(Request $request, Post $post) { $post->update($request->validated()); } ``` Correct: ```php public function update(UpdatePostRequest $request, Post $post) { Gate::authorize('update', $post); $post->update($request->validated()); } ``` Or via Form Request: ```php public function authorize(): bool { return $this->user()->can('update', $this->route('post')); } ``` ## Prevent SQL Injection Always use parameter binding. Never interpolate user input into queries. Incorrect: ```php DB::select("SELECT * FROM users WHERE name = '{$request->name}'"); ``` Correct: ```php User::where('name', $request->name)->get(); // Raw expressions with bindings User::whereRaw('LOWER(name) = ?', [strtolower($request->name)])->get(); ``` ## Escape Output to Prevent XSS Use `{{ }}` for HTML escaping. Only use `{!! !!}` for trusted, pre-sanitized content. Incorrect: ```blade {!! $user->bio !!} ``` Correct: ```blade {{ $user->bio }} ``` ## CSRF Protection Include `@csrf` in all POST/PUT/DELETE Blade forms. Not needed in Inertia. Incorrect: ```blade
``` Correct: ```blade ``` ## Rate Limit Auth and API Routes Apply `throttle` middleware to authentication and API routes. ```php RateLimiter::for('login', function (Request $request) { return Limit::perMinute(5)->by($request->ip()); }); Route::post('/login', LoginController::class)->middleware('throttle:login'); ``` ## Validate File Uploads Validate MIME type, extension, and size. Never trust client-provided filenames. ```php public function rules(): array { return [ 'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'], ]; } ``` Store with generated filenames: ```php $path = $request->file('avatar')->store('avatars', 'public'); ``` ## Keep Secrets Out of Code Never commit `.env`. Access secrets via `config()` only. Incorrect: ```php $key = env('API_KEY'); ``` Correct: ```php // config/services.php 'api_key' => env('API_KEY'), // In application code $key = config('services.api_key'); ``` ## Audit Dependencies Run `composer audit` periodically to check for known vulnerabilities in dependencies. Automate this in CI to catch issues before deployment. ```bash composer audit ``` ## Encrypt Sensitive Database Fields Use `encrypted` cast for API keys/tokens and mark the attribute as `hidden`. Incorrect: ```php class Integration extends Model { protected function casts(): array { return [ 'api_key' => 'string', ]; } } ``` Correct: ```php class Integration extends Model { protected $hidden = ['api_key', 'api_secret']; protected function casts(): array { return [ 'api_key' => 'encrypted', 'api_secret' => 'encrypted', ]; } } ```