Mengeraskan aplikasi: membedakan middleware global dan route middleware, membuat custom middleware, melindungi form dengan token @csrf, mencegah XSS lewat escape output Blade, serta TrustProxies dan VerifyCsrfToken.

Keamanan bukan fitur yang dipasang di akhir — ia adalah kebiasaan yang dibangun di setiap lapisan. Di episode ini kita gabungkan dua sisi keamanan web yang paling sering diserang: CSRF (Cross-Site Request Forgery) dan XSS (Cross-Site Scripting), plus mekanisme yang menegakkannya: middleware.
Laravel sudah melindungi kalian secara default — tugas kalian adalah memahami apa yang dilindungi, agar tidak sengaja melemahkannya.
Middleware adalah lapisan yang memproses request sebelum masuk controller. Dua jenis pemasangan:
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
EnsureUserIsActive::class,
]);
})Global middleware jalan untuk semua request. Route middleware dipasang per-route:
Route::get('/admin', [AdminController::class, 'index'])
->middleware(['auth', 'admin']);Urutan eksekusi: global → group (web/api) → route middleware.
Buat middleware dengan artisan:
php artisan make:middleware EnsureUserIsActive<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureUserIsActive
{
public function handle(Request $request, Closure $next): Response
{
if (!$request->user()?->is_active) {
abort(403, 'Akun Anda tidak aktif.');
}
return $next($request);
}
}$next($request) meneruskan request ke lapisan berikutnya. Middleware adalah tempat yang tepat untuk: otentikasi, otorisasi, rate limiting, pemilihan bahasa, header keamanan, dan logging.
CSRF menipu browser user untuk mengirim request berbahaya ke aplikasi yang sudah di-login — misalnya lewat gambar <img> yang memicu request POST /logout atau transfer dana. Laravel menangkisnya dengan token CSRF yang unik per session: request POST tanpa token yang valid akan ditolak (VerifyCsrfToken middleware).
Setiap form POST wajib menyertakan token:
<form method="POST" action="{{ route('posts.store') }}">
@csrf
<!-- ... -->
</form>@csrf me-render <input type="hidden" name="_token" value="...">. Untuk request API/JavaScript, token dikirim lewat header X-CSRF-TOKEN atau diambil dari meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">fetch('/api/endpoint', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
});Warning
Jangan pernah mengecualikan route dari CSRF tanpa alasan kuat. Jika sebuah route POST dikecualikan di $except, route itu bisa dieksekusi tanpa token — dan berpotensi dieksploitasi. Pengecualian hanya dibenarkan untuk webhook eksternal yang memang tidak membawa session, itupun dengan verifikasi tanda tangan (signature) yang ketat.
XSS terjadi saat input user ditampilkan tanpa di-escape, sehingga skrip <script> ikut dieksekusi browser. Laravel menangkisnya di lapisan output:
{{ $var }} → di-escape otomatis (htmlspecialchars).{!! $var !!} → tidak di-escape — sumber XSS jika salah pakai (kita bahas di episode 6).Aturan praktisnya sederhana: data dari user hanya tampil lewat {{ }}. Konten yang memang harus render HTML (hasil markdown) harus di-sanitize dulu — misalnya dengan package purifier — bukan asal dibungkus {!! !!}.
Juga sanitasikan input di sisi server: strip_tags atau aturan validasi untuk membatasi isi field (misalnya aturan alpha_num, regex) di Form Request.
Middleware ini memvalidasi token CSRF pada setiap request yang tidak idempotent (POST/PUT/PATCH/DELETE). Di Laravel modern konfigurasinya di bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'stripe/webhook', // webhook yang diverifikasi signature
]);
})Saat aplikasi berada di belakang proxy (Nginx, Cloudflare, AWS ALB), Laravel harus tahu proxy mana yang tepercaya agar HTTPS dan IP asli terdeteksi benar:
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(at: '*'); // kencangkan sesuai infra
})Jika TrustProxies salah, hal-hal tak terduga terjadi: request()->secure() selalu false, request()->ip() mengembalikan IP proxy, dan redirect http/https menjadi kacau — terutama saat memakai Route::redirect() atau middleware HTTPS.
| Lapisan | Kontrol Laravel |
|---|---|
| Form submission | Token @csrf wajib di setiap form POST |
| Output | {{ }} untuk semua data user |
| Input | Validasi + sanitasi di Form Request |
| Login | auth middleware, rate limit login |
| Header | Middleware kustom untuk X-Content-Type-Options, HSTS, dsb. |
Inti yang harus dibawa pulang:
make:middleware.@csrf; jangan pernah mengecualikan route tanpa alasan kuat.{{ }} untuk data user, {!! !!} hanya untuk HTML ter-sanitize.Di episode 17 selanjutnya kita akan membahas API development (REST) — route api.php, API Resources sebagai transformer, JSON responses yang konsisten, versioning, pagination, dan dokumentasi API dengan Scribe. Sampai jumpa di episode 17!