Belajar Laravel - Security: CSRF, XSS & Middleware
Episode 16 of 24

Belajar Laravel - Security: CSRF, XSS & Middleware

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.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

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: Global vs Route

Middleware adalah lapisan yang memproses request sebelum masuk controller. Dua jenis pemasangan:

Global middleware - bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->web(append: [
        EnsureUserIsActive::class,
    ]);
})

Global middleware jalan untuk semua request. Route middleware dipasang per-route:

Route middleware
Route::get('/admin', [AdminController::class, 'index'])
    ->middleware(['auth', 'admin']);

Urutan eksekusi: global → group (web/api) → route middleware.

Custom Middleware

Buat middleware dengan artisan:

Buat custom middleware
php artisan make:middleware EnsureUserIsActive
app/Http/Middleware/EnsureUserIsActive.php
<?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: Melindungi Form dari Serangan

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:

Token CSRF di form
<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 tag CSRF untuk JavaScript
<meta name="csrf-token" content="{{ csrf_token() }}">
Kirim token via fetch
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: Escape Output di Blade

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.

VerifyCsrfToken dan TrustProxies

VerifyCsrfToken

Middleware ini memvalidasi token CSRF pada setiap request yang tidak idempotent (POST/PUT/PATCH/DELETE). Di Laravel modern konfigurasinya di bootstrap/app.php:

Kecualikan route dari CSRF (hati-hati)
->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'stripe/webhook',   // webhook yang diverifikasi signature
    ]);
})

TrustProxies

Saat aplikasi berada di belakang proxy (Nginx, Cloudflare, AWS ALB), Laravel harus tahu proxy mana yang tepercaya agar HTTPS dan IP asli terdeteksi benar:

Trust proxies
->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.

Ceklis Keamanan Dasar

LapisanKontrol Laravel
Form submissionToken @csrf wajib di setiap form POST
Output{{ }} untuk semua data user
InputValidasi + sanitasi di Form Request
Loginauth middleware, rate limit login
HeaderMiddleware kustom untuk X-Content-Type-Options, HSTS, dsb.

Penutup

Inti yang harus dibawa pulang:

  • Middleware global berlaku semua request; route middleware per-route; custom middleware dibuat dengan make:middleware.
  • CSRF: setiap form wajib @csrf; jangan pernah mengecualikan route tanpa alasan kuat.
  • XSS: {{ }} untuk data user, {!! !!} hanya untuk HTML ter-sanitize.
  • TrustProxies penting saat aplikasi di belakang proxy agar HTTPS & IP benar.

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!

Belajar Laravel - Security: CSRF, XSS & Middleware | Belajar Laravel