Güvenlik Açığının Açıklaması
Siteler arası istek sahteciliğine aşina değilseniz, bu güvenlik açığının nasıl istismar edilebileceğine dair bir örneği ele alalım. Uygulamanızın, kimliği doğrulanmış kullanıcının e-posta adresini değiştirmek için bir POST isteği kabul eden bir /user/email rotası olduğunu düşünün. Büyük olasılıkla, bu rota, kullanıcının kullanmaya başlamak istediği e-posta adresini içeren bir e-posta giriş alanı bekler. CSRF koruması olmadan, kötü niyetli bir web sitesi uygulamanızın /user/email rotasına işaret eden ve kötü niyetli kullanıcının kendi e-posta adresini gönderen bir HTML formu oluşturabilir:
<form action="https://your-application.com/user/email" method="POST">
<input type="email" value="malicious-email@example.com">
</form>
<script>
document.forms[0].submit();
</script>Kötü amaçlı web sitesi sayfa yüklendiğinde formu otomatik olarak gönderiyorsa, kötü amaçlı kullanıcının tek yapması gereken uygulamanızın şüphelenmeyen bir kullanıcısını kendi web sitesini ziyaret etmeye ikna etmek ve uygulamanızdaki e-posta adresini değiştirmektir. Bu açığı önlemek için, kötü amaçlı uygulamanın erişemediği gizli bir oturum değerine yönelik gelen her POST, PUT, PATCH veya DELETE isteğini incelememiz gerekir.CSRF İsteklerini Önleme
Laravel, uygulama tarafından yönetilen her etkin kullanıcı oturumu için otomatik olarak bir CSRF "token" üretir. Bu token, kimliği doğrulanmış kullanıcının aslında uygulamaya istekleri yapan kişi olduğunu doğrulamak için kullanılır. Bu token, kullanıcının oturumunda saklandığından ve oturum her yeniden oluşturulduğunda değiştiğinden, kötü amaçlı bir uygulama buna erişemez.
Mevcut oturumun CSRF belirtecine, isteğin oturumu veya csrf_token yardımcı fonksiyonu aracılığıyla erişilebilir:
use Illuminate\Http\Request;
Route::get('/token', function (Request $request) {
$token = $request->session()->token();
$token = csrf_token();
// ...
});Uygulamanızda bir "POST", "PUT", "PATCH" veya "DELETE" HTML formu tanımladığınızda, CSRF koruma ara yazılımının isteği doğrulayabilmesi için forma gizli bir CSRF _token alanı eklemelisiniz. Kolaylık olması açısından, gizli token giriş alanını oluşturmak için @csrf Blade yönergesini kullanabilirsiniz:<form method="POST" action="/profile">
@csrf
<!-- Equivalent to... -->
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>Varsayılan olarak web middleware grubuna dahil olan IlluminateFoundationHttpMiddlewareValidateCsrfToke n middleware, istek girdisindeki token'ın oturumda depolanan token'la eşleştiğini otomatik olarak doğrulayacaktır. Bu iki token eşleştiğinde, kimliği doğrulanmış kullanıcının isteği başlatan kullanıcı olduğunu biliriz.CSRF Tokenları ve SPA'ları
API arka ucu olarak Laravel kullanan bir SPA oluşturuyorsanız, API'nizle kimlik doğrulaması yapma ve CSRF güvenlik açıklarına karşı koruma hakkında bilgi edinmek için Laravel Sanctum belgelerine başvurmalısınız.
URI'leri CSRF Korumasından Hariç Tutma
Bazen bir URI kümesini CSRF korumasından hariç tutmak isteyebilirsiniz. Örneğin, ödemeleri işlemek için Stripe kullanıyorsanız ve webhook sistemlerini kullanıyorsanız, Stripe rotalarınıza hangi CSRF belirtecini göndereceğini bilmediğinden, Stripe webhook işleyici rotanızı CSRF korumasından hariç tutmanız gerekecektir. Genellikle, bu tür rotaları Laravel'in route/web.php dosyasındaki tüm rotalara uyguladığı web ara yazılım grubunun dışına yerleştirmelisiniz. Ancak, uygulamanızın bootstrap/app.php dosyasındaki validateCsrfTokens yöntemine URI'lerini sağlayarak belirli rotaları da hariç tutabilirsiniz:
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
]);
})X-CSRF-TOKENCSRF belirtecini POST parametresi olarak kontrol etmenin yanı sıra, varsayılan olarak web ara yazılım grubuna dahil olan IlluminateFoundationHttpMiddlewareValidateCsrfToke n ara yazılımı, X-CSRF-TOKEN istek başlığını da kontrol edecektir. Örneğin, belirteci bir HTML meta etiketinde saklayabilirsiniz:
<meta name="csrf-token" content="{{ csrf_token() }}">Daha sonra, jQuery gibi bir kütüphaneye belirteci tüm istek başlıklarına otomatik olarak eklemesini söyleyebilirsiniz. Bu, eski JavaScript teknolojisini kullanan AJAX tabanlı uygulamalarınız için basit, kullanışlı CSRF koruması sağlar:$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});X-XSRF-TOKENLaravel, geçerli CSRF belirtecini, framework tarafından oluşturulan her yanıtla birlikte gelen şifrelenmiş bir XSRF-TOKEN çerezinde depolar. Çerez değerini kullanarak X-XSRF-TOKEN istek başlığını ayarlayabilirsiniz. Bu çerez, esas olarak geliştiricilere kolaylık sağlamak amacıyla gönderilir; çünkü Angular ve Axios gibi bazı JavaScript çerçeveleri ve kütüphaneleri, aynı kökenli isteklerde değerini otomatik olarak X-XSRF-TOKEN başlığına yerleştirir.