محافظت در برابر CSRF

تزریق درخواست بین سایتی (Cross-Site Request Forgery) نوعی حمله است که در آن یک فرم HTML در سایتی خارجی و تحت کنترل مهاجم استفاده می‌شود تا حمله‌ای را به سایت هدف انجام دهد.

سناریوی زیر را تصور کنید:

- شما به عنوان مدیر یک سایت جوملا وارد سیستم شده‌اید

- در همان مرورگر می‌خواهید از یک فروشگاه آنلاین تلویزیون خیلی ارزان بخرید که یک فرد ناشناس آدرس آن را برای شما ایمیل کرده است

- روی دکمه «افزودن به سبد خرید» کلیک می‌کنید اما به جای اینکه کالا به سبد خرید اضافه شود، وارد بخش مدیریت جوملای سایت خود می‌شوید و پیغام تأیید «کاربر افزوده شد» را مشاهده می‌کنید

چه اتفاقی افتاده؟ شما مورد حمله قرار گرفته‌اید! فرم «افزودن به سبد خرید» در فروشگاه توسط مهاجم به صورت زیر دستکاری شده است:

 
<form action="https://myjoomlasite.com/administrator/index.php" method="post">
    <input type="hidden" name="task" value="user.add" />
    <input type="hidden" name="option" value="com_users" />
    <input type="hidden" name="jform[username]" value="attackeruser" />
    <input type="hidden" name="jform[password]" value="attackerpwd123" />
    <input type="submit" value="Add to cart" />
</form>

ویژگی `action` فرم به سایت قربانی اشاره دارد و بنابراین داده‌های فرم بین دو سایت جعل شده است؛ این همان حمله CSRF است. در این مثال، CSRF برای ایجاد یک کاربر جدید برای مهاجم استفاده شده و چون این درخواست با دسترسی‌های کاربر وارد شده اجرا می‌شود، موفقیت‌آمیز است.

خوشبختانه جوملا این حملات را با یک اقدام امنیتی ساده جلوگیری می‌کند.

راه پیشگیری

برای جلوگیری از حملات CSRF، یک رشته تصادفی به هر درخواستی که قرار است تغییراتی در سایت ایجاد کند اضافه می‌شود:

<form action="index.php" method="post">
    [...]
    <?php echo HTMLHelper::_('form.token'); ?>
</form>

 متد `form.token` یک فیلد ورودی مخفی با نام تصادفی و مقدار "1" ایجاد می‌کند. این نام تصادفی در نشست کاربری ذخیره می‌شود و جوملا بعد از ارسال فرم چک می‌کند که این فیلد در درخواست وجود دارد یا خیر. برای فعال‌سازی این بررسی، در کلاس‌های کنترلر از متد `$this->checkToken();` و خارج از کنترلرها از متد `Session::checkToken()` استفاده کنید.

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

نکته مهم: توکن‌های CSRF ربطی به بررسی دسترسی‌ها ندارند! فقط عبور از CSRF به معنای ورود کاربر یا داشتن مجوزهای خاص برای انجام وظیفه مشخص نیست.