پرش به محتویات

🛡️ حمله CSRF چیه و چگونه از اون جلوگیری کنیم؟

📌 CSRF چیه؟

CSRF یا "تقلب در درخواست‌های متقابل" (Cross-Site Request Forgery) نوعی حمله تحت وب است که در آن حمله‌گر با فریب کاربر، بدون اینکه او متوجه شود، درخواست‌های ناخواسته‌ای به سایتی که قبلاً وارد آن شده ارسال می‌کند. این حمله از اعتماد موجود بین مرورگر کاربر و سرور سوء استفاده می‌کند؛ چرا که مرورگر به‌طور خودکار کوکی‌ها و اطلاعات احراز هویت را در هر درخواست ارسال می‌کند. در نتیجه، حتی اگر کاربر آگاه نباشد، درخواست‌های مخربی که توسط حمله‌گر تنظیم شده‌اند، ممکن است به عنوان درخواست‌های معتبر شناخته شده و اجرا شوند. این موضوع می‌تواند منجر به تغییر اطلاعات حساب کاربری، انتقال وجوه، تغییر تنظیمات امنیتی یا افشای داده‌های حساس شود. برخلاف حملات XSS که کد مخرب در سایت هدف تزریق می‌شود، در CSRF خود سایت هدف مورد حمله قرار نمی‌گیرد بلکه از اعتبار کاربر استفاده می‌شود.


⚠️ مثال‌های واقعی از حملات CSRF

۱. تغییر تنظیمات امنیتی حساب کاربری در یک سرویس ایمیل

فرض کنید کاربری در سرویس ایمیل خود (مثلاً mail.com) وارد حساب کاربری شده و دسترسی لازم برای تغییر تنظیمات امنیتی، مانند تغییر رمز عبور یا فعال‌سازی احراز هویت دو مرحله‌ای را دارد. یک حمله‌گر می‌تواند صفحه‌ای طراحی کند که در پس‌زمینه به صورت خودکار درخواست تغییر رمز عبور و فعال‌سازی تنظیمات امنیتی را ارسال کند. به عنوان مثال:

<img src="https://mail.com/update-settings?password=newSecretPass123&enable_2FA=true" style="display:none;" />

در این سناریو، اگر کاربر همزمان در سایت دیگری حضور داشته باشد یا صفحه‌ی مخربی باز شود، مرورگر اطلاعات احراز هویت (کوکی‌ها) را به همراه درخواست ارسال می‌کند و تغییرات ناخواسته اعمال می‌شود. این مثال پیچیده‌تر و واقعی‌تر است چرا که تغییر تنظیمات امنیتی، به ویژه تغییر رمز عبور و فعال‌سازی احراز هویت دو مرحله‌ای، می‌تواند کنترل کامل حساب کاربری را به دست حمله‌گر بدهد.


۲. تغییر ایمیل کاربر بدون اجازه

یک حمله‌گر می‌تواند فرم مخرب زیر را در یک ایمیل یا صفحه وب جاسازی کند:

<form action="https://social.com/update-email" method="POST">
  <input type="hidden" name="email" value="hacker@mail.com" />
  <input type="submit" />
</form>
<script>
  document.forms[0].submit();
</script>

با ارسال خودکار این فرم، ایمیل حساب کاربری به آدرس هکر تغییر داده می‌شود و کنترل حساب به دست مهاجم می‌افتد. 😱


🛑 روش‌های جلوگیری از CSRF و توضیحات آن‌ها

✅ ۱. استفاده از توکن CSRF (بهترین روش)

توضیح:
سرور برای هر فرم یک توکن یکتا و تصادفی تولید می‌کند که در فرم به عنوان یک ورودی مخفی قرار می‌گیرد. هنگام ارسال فرم، سرور توکن ارسال شده را با توکن ذخیره‌شده مقایسه می‌کند. اگر توکن‌ها مطابقت نداشته باشند، درخواست رد می‌شود. این روش موثر است زیرا حمله‌گر به سادگی نمی‌تواند توکن تصادفی و یکتا را پیش‌بینی یا استخراج کند.

<form action="/transfer" method="POST">
  <input type="hidden" name="csrf_token" value="random12345" />
  <input type="text" name="amount" />
  <input type="submit" value="انتقال وجه" />
</form>

✅ ۲. تنظیم SameSite برای کوکی‌ها

توضیح:
ویژگی SameSite در کوکی‌ها تعیین می‌کند که کوکی‌ها تنها در درخواست‌هایی که از دامنه‌ی اصلی ارسال می‌شوند، گنجانده شوند. با تنظیم SameSite=Strict یا SameSite=Lax، حتی اگر درخواست از یک دامنه خارجی ارسال شود، کوکی‌های مربوط به احراز هویت ارسال نخواهند شد. به این ترتیب، حمله‌گر که در دامنه دیگری فعالیت می‌کند، نمی‌تواند به اطلاعات حساس دسترسی پیدا کند.

نمونه کد در Express.js:

app.use(
  cookieSession({
    name: "session",
    secret: "supersecret",
    cookie: { sameSite: "Strict" },
  })
);

✅ ۳. بررسی هدرهای Origin و Referer

توضیح:
در این روش، سرور مبدا درخواست (دامنه‌ای که درخواست از آن ارسال شده) را از طریق هدرهای Origin یا Referer بررسی می‌کند. اگر دامنه مبدا با دامنه معتبر مطابقت نداشته باشد، درخواست رد می‌شود. این اقدام تضمین می‌کند که فقط درخواست‌های ارسالی از منابع معتبر پردازش شوند و از درخواست‌های مخرب که از دامنه‌های نامعتبر ارسال شده‌اند، جلوگیری می‌شود.

نمونه کد در Flask (پایتون):

from flask import request, abort

@app.route('/transfer', methods=['POST'])
def transfer():
    if request.headers.get('Origin') != 'https://bank.com':
        abort(403)
    # پردازش درخواست

✅ ۴. استفاده از رمز عبور/OTP برای عملیات حساس

توضیح:
در برخی عملیات‌های حساس مانند تغییر رمز عبور یا انتقال وجه، حتی اگر درخواست مخرب از طریق CSRF ارسال شود، اضافه کردن یک لایه امنیتی اضافی مانند درخواست رمز عبور یا OTP (رمز یکبار مصرف) از کاربر، تضمین می‌کند که عملیات تنها با تایید صریح کاربر انجام شود. این روش مانع از اجرای خودکار عملیات‌های حساس بدون آگاهی و تأیید کاربر می‌شود.


✅ ۵. عدم استفاده از متد GET برای عملیات حساس

توضیح:
متد GET برای دریافت اطلاعات طراحی شده و استفاده از آن در عملیات‌های تغییر‌دهنده وضعیت مانند انتقال وجه یا تغییر تنظیمات می‌تواند خطرناک باشد؛ زیرا درخواست‌های GET به‌راحتی از طریق لینک‌ها، تصاویر یا سایر المان‌های HTML ایجاد می‌شوند. استفاده از متد POST که نیازمند یک فرم یا درخواست آگاهانه کاربر است، مانع از بروز حملات CSRF می‌شود.

نمونه نادرست:

<a href="https://bank.com/transfer?to=attacker&amount=1000000">انتقال وجه</a>

نمونه صحیح:

<form action="/transfer" method="POST">
  <input type="text" name="amount" />
  <input type="submit" value="انتقال وجه" />
</form>

🎯 جمع‌بندی

برای مقابله با حملات CSRF:

  • ✔️ از توکن CSRF در فرم‌ها استفاده کنید؛ زیرا این توکن‌ها تنها یکبار قابل استفاده هستند و از پیش‌بینی آن‌ها توسط حمله‌گر جلوگیری می‌شود.
  • ✔️ کوکی‌ها را با استفاده از ویژگی SameSite محدود کنید تا از ارسال خودکار کوکی‌ها در درخواست‌های میان‌دامنه جلوگیری شود.
  • ✔️ هدرهای Origin و Referer را بررسی کنید تا اطمینان حاصل شود که درخواست از دامنه معتبر ارسال شده است.
  • ✔️ برای عملیات حساس از تأیید دو مرحله‌ای (رمز عبور یا OTP) استفاده کنید تا حتی در صورت موفقیت یک حمله CSRF، عملیات بدون تایید کاربر انجام نشود.
  • ✔️ از متد POST به جای GET برای درخواست‌های حساس استفاده کنید تا از بروز درخواست‌های ناخواسته از طریق لینک‌ها یا تصاویر جلوگیری شود.

با این اقدامات و پیاده‌سازی لایه‌های متعدد امنیتی، می‌توانید امنیت برنامه‌های وب خود را در برابر حملات CSRF به طور قابل توجهی افزایش دهید! 🔒


👥 Contributors

Mohammad Mohagheghian