Siteler arası istek sahteciliği, kimliği doğrulanmış bir kullanıcı adına yetkisiz komutların gerçekleştirildiği bir tür kötü amaçlı istismardır. Neyse ki
Laravel, uygulamanızı siteler arası istek sahteciliği
(CSRF) saldırılarından korumayı kolaylaştırır.
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-TOKEN CSRF 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-TOKEN Laravel, 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.