Introductie
Laravel biedt ingebouwde bescherming tegen de meest voorkomende kwetsbaarheden in webapplicaties, maar deze moeten correct worden gebruikt. Dit behandelt essentiële beveiligingspraktijken zoals bescherming tegen mass assignment, het voorkomen van SQL-injectie, XSS-escaping, CSRF-bescherming, validatie van bestandsuploads, rate limiting en het versleutelen van gevoelige databasevelden. Voor autorisatiepatronen, zie Gebruik Policies en Gates voor Autorisatie.
Waarom
- Defense in depth: Elke praktijk pakt een andere aanvalsvector aan, samen dekken ze de OWASP Top 10-risico's die relevant zijn voor Laravel-applicaties
- Framework-ondersteuning: Laravel biedt alle tools al; je hoeft ze alleen consistent te gebruiken
- Gegevensbescherming: Het versleutelen van gevoelige velden en het buiten de code houden van secrets beschermt tegen datalekken
- Beschikbaarheid: Rate limiting voorkomt brute-force-aanvallen en misbruik van authenticatie- en API-endpoints
Geschikt voor
- Alle Laravel-applicaties, ongeacht de omvang
- Applicaties die gebruikersinvoer, authenticatie of bestandsuploads verwerken
- Applicaties die gevoelige gegevens opslaan (API-sleutels, tokens, persoonlijke informatie)
Minder geschikt voor
- N.v.t., deze praktijken zijn van toepassing op elke Laravel-applicatie
Voorbeelden
Bescherming tegen mass assignment
Elk model moet $fillable (whitelist) of $guarded (blacklist) definiëren:
// Slecht: alle velden zijn mass assignable
class User extends Model
{
protected $guarded = [];
}
// Goed: expliciete whitelist
class User extends Model
{
protected $fillable = [
'name',
'email',
'password',
];
}
Gebruik nooit $guarded = [] op models die gebruikersinvoer accepteren.
Voorkom SQL-injectie
Gebruik altijd parameter binding. Interpoleer nooit gebruikersinvoer in queries:
// Slecht: kwetsbaarheid voor SQL-injectie
DB::select("SELECT * FROM users WHERE name = '{$request->name}'");
// Goed: parameter binding
User::where('name', $request->name)->get();
// Goed: raw expressies met bindings
User::whereRaw('LOWER(name) = ?', [strtolower($request->name)])->get();
Escape output om XSS te voorkomen
Gebruik {{ }} voor HTML-escaping. Gebruik {!! !!} alleen voor vertrouwde, vooraf gesaniteerde content:
{{-- Slecht: niet-geëscapete gebruikerscontent --}}
{!! $user->bio !!}
{{-- Goed: automatisch geëscaped --}}
{{ $user->bio }}
CSRF-bescherming
Voeg @csrf toe aan alle POST/PUT/DELETE Blade-formulieren:
<form method="POST" action="/posts">
@csrf
<input type="text" name="title">
</form>
Rate limiting voor auth- en API-routes
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip());
});
Route::post('/login', LoginController::class)->middleware('throttle:login');
Valideer bestandsuploads
Valideer MIME-type, extensie en grootte. Vertrouw nooit door de client aangeleverde bestandsnamen:
public function rules(): array
{
return [
'avatar' => ['required', 'image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
];
}
Sla op met gegenereerde bestandsnamen:
$path = $request->file('avatar')->store('avatars', 'public');
Versleutel gevoelige databasevelden
Gebruik de encrypted-cast voor API-sleutels en tokens, en markeer het attribuut als hidden:
class Integration extends Model
{
protected $hidden = ['api_key', 'api_secret'];
protected function casts(): array
{
return [
'api_key' => 'encrypted',
'api_secret' => 'encrypted',
];
}
}
Controleer dependencies
Voer composer audit periodiek uit en automatiseer het in CI:
composer audit