حفاظت CSRF
معرفی
جعل درخواست های بین سایتی نوعی سوء استفاده مخرب است که به موجب آن دستورات غیرمجاز از طرف یک کاربر احراز هویت شده انجام می شود. خوشبختانه، لاراول محافظت از برنامه شما را در برابر حملات جعل درخواست بین سایتی (CSRF) آسان می کند.
توضیحی در مورد آسیب پذیری
در صورتی که با جعل درخواست های متقابل سایت آشنا نیستید، بیایید نمونه ای از نحوه سوء استفاده از این آسیب پذیری را مورد بحث قرار دهیم. تصور کنید برنامه شما
/user/email
مسیری دارد که
POST
درخواست تغییر آدرس ایمیل کاربر احراز هویت شده را می پذیرد. به احتمال زیاد، این مسیر انتظار دارد که یک
email
فیلد ورودی حاوی آدرس ایمیلی باشد که کاربر مایل به استفاده از آن است.
بدون حفاظت CSRF، یک وب سایت مخرب می تواند یک فرم HTML ایجاد کند که به مسیر برنامه شما اشاره می کند
/user/email
و آدرس ایمیل خود کاربر مخرب را ارسال می کند:
<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>
اگر وبسایت مخرب بهطور خودکار فرم را هنگام بارگیری صفحه ارسال کند، کاربر مخرب فقط باید یک کاربر ناخواسته از برنامه شما را برای بازدید از وبسایت خود فریب دهد و آدرس ایمیل او در برنامه شما تغییر میکند.
برای جلوگیری از این آسیبپذیری، باید هر ورودی
POST
،
PUT
,
PATCH
یا
DELETE
درخواست مقدار جلسه مخفی را که برنامه مخرب قادر به دسترسی به آن نیست، بررسی کنیم.
جلوگیری از درخواست CSRF
لاراول برای هر جلسه کاربر فعال که توسط برنامه مدیریت می شود، به طور خودکار یک "توکن" CSRF تولید می کند. این نشانه برای تأیید اینکه کاربر احراز هویت شده شخصی است که واقعاً درخواست ها را به برنامه ارائه می دهد استفاده می شود. از آنجایی که این نشانه در جلسه کاربر ذخیره می شود و هر بار که جلسه بازسازی می شود تغییر می کند، یک برنامه مخرب قادر به دسترسی به آن نیست.
نشانه CSRF جلسه جاری از طریق جلسه درخواست یا از طریق
csrf_token
تابع کمکی قابل دسترسی است:
use Illuminate\Http\Request; Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});
هر زمان که فرم HTML "POST"، "PUT"، "PATCH" یا "DELETE" را در برنامه خود تعریف می کنید، باید یک
_token
فیلد CSRF مخفی را در فرم اضافه کنید تا میان افزار حفاظت CSRF بتواند درخواست را تایید کند. برای راحتی، می توانید از
@csrf
دستورالعمل Blade برای ایجاد فیلد ورودی رمز پنهان استفاده کنید:
<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>
میانافزار
که بهطور پیشفرض در گروه میانافزار گنجانده شده است ،
Illuminate\Foundation\Http\Middleware\ValidateCsrfToken
بهطور
web
خودکار تأیید میکند که نشانه موجود در ورودی درخواست با توکن ذخیرهشده در جلسه مطابقت دارد. هنگامی که این دو نشانه با هم مطابقت دارند، می دانیم که کاربر تأیید شده کسی است که درخواست را آغاز می کند.
توکنها و اسپاهای CSRF
اگر در حال ساخت SPA هستید که از لاراول به عنوان پشتیبان API استفاده می کند، باید برای اطلاعات در مورد احراز هویت با API خود و محافظت در برابر آسیب پذیری های CSRF به اسناد Laravel Sanctum مراجعه کنید.
مستثنی کردن URI ها از حفاظت CSRF
گاهی اوقات ممکن است بخواهید مجموعه ای از URI ها را از حفاظت CSRF حذف کنید. به عنوان مثال، اگر از Stripe برای پردازش پرداختها استفاده میکنید و از سیستم webhook آنها استفاده میکنید، باید مسیر کنترلر Stripe webhook خود را از حفاظت CSRF حذف کنید، زیرا Stripe نمیداند چه توکن CSRF را به مسیرهای شما ارسال کند.
به طور معمول، شما باید این نوع مسیرها را خارج از
web
گروه میان افزاری که لاراول برای همه مسیرهای موجود در
routes/web.php
فایل اعمال می کند، قرار دهید. با این حال، میتوانید مسیرهای خاصی را با ارائه URI آنها به
validateCsrfTokens
روش موجود در فایل برنامه خود حذف کنید
bootstrap/app.php
:
->withMiddleware(function (Middleware $middleware) { $middleware->validateCsrfTokens(except: [ 'stripe/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ]);})
برای راحتی، میانافزار CSRF هنگام اجرای آزمایشها بهطور خودکار برای همه مسیرها غیرفعال میشود .
X-CSRF-TOKEN
علاوه بر بررسی توکن CSRF به عنوان پارامتر POST، میان افزار که
به طور پیش فرض
Illuminate\Foundation\Http\Middleware\ValidateCsrfToken
در گروه میان افزار قرار دارد ،
هدر درخواست را نیز بررسی می کند. به عنوان مثال می توانید توکن را در یک
تگ HTML ذخیره کنید:
web
X-CSRF-TOKEN
meta
<meta name="csrf-token" content="{{ csrf_token() }}">
سپس، میتوانید به کتابخانهای مانند jQuery دستور دهید تا توکن را بهطور خودکار به تمام سرصفحههای درخواست اضافه کند. این محافظت ساده و راحت CSRF را برای برنامه های مبتنی بر AJAX با استفاده از فناوری جاوا اسکریپت قدیمی فراهم می کند:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }});
X-XSRF-TOKEN
لاراول توکن CSRF فعلی را در یک
XSRF-TOKEN
کوکی رمزگذاری شده ذخیره می کند که با هر پاسخ تولید شده توسط فریم ورک گنجانده شده است. می توانید از مقدار کوکی برای تنظیم
X-XSRF-TOKEN
هدر درخواست استفاده کنید.
این کوکی در درجه اول به عنوان یک راحتی برنامهنویس ارسال میشود زیرا برخی از چارچوبها و کتابخانههای جاوا اسکریپت، مانند Angular و Axios، بهطور خودکار مقدار آن را در هدر
X-XSRF-TOKEN
در درخواستهای با منبع یکسان قرار میدهند.
به طور پیش فرض،
resources/js/bootstrap.js
فایل شامل کتابخانه Axios HTTP است که به طور خودکارX-XSRF-TOKEN
هدر را برای شما ارسال می کند.