زیردامنهٔ مدیریتی CSRF را متوقف نمیکند: چهار بررسی پیش از راهاندازی
نام میزبان تازه مبدأ تازه است، بیشتر وقتها همان سایت، پس کوکیهای same-site و فرمهای ساده از آن میگذرند. توکنها، دروازه و مجوز را بررسی کنید.
انتقال رابط مدیریتی به admin.example.com یک بهبود واقعی است: کوکیهای مدیریتی را از صفحههای عمومی دور نگه میدارد، به دو برنامه حافظهٔ نهان جدا میدهد و میگذارد سیاست شبکهٔ سختگیرانهتری را به یک نام میزبان معطوف کنید. اما این کنترل CSRF نیست و کد سایت عمومی را برای باز گذاشتن در برابر مدیر واردشده ایمن نمیکند. جداسازی آنچه مرورگر مرز میداند را عوض میکند، نه آنچه سرور بررسی میکند، پس پیش از تمامشده دانستن کار این چهار بررسی را انجام دهید.
مبدأ و سایت را دو واژهٔ متفاوت بخوانید
مبدأ یعنی طرح، میزبان و درگاه، پس https://www.example.com و https://admin.example.com دو مبدأ متفاوتاند. سایت به معنای SameSite یعنی طرح بهعلاوهٔ دامنهٔ قابل ثبت، پس همان دو نام میزبان معمولاً یک سایتاند. همین تفاوت تمام تله است: ویژگی SameSite بین زیردامنههای همخانواده کمکی نمیکند، چون مرورگر درخواست را اصلاً میانسایتی نمیداند. رابط مدیریتی را به دامنهٔ قابل ثبت واقعاً دیگری مانند admin-example.net ببرید، آنگاه درخواست واقعاً میانسایتی میشود و همانجاست که SameSite=Lax یا Strict کاری را شروع میکند که میتوان به آن تکیه کرد.
آن را در مرورگر بیازمایید، نه با استدلال.
سایت عمومی را بار کنید، ابزار توسعهدهنده را باز کنید و ببینید مرورگر کدام کوکیها را به درخواست سوی میزبان مدیریتی میچسباند. اگر کوکی ویژگی Domain ندارد فقط مخصوص میزبان است و روی نام خودش میماند؛ اگر Domain=example.com دارد به هر خواهر میرود و زیردامنهٔ تازه برای آن کوکی چیزی به شما نداده است.
خواندن پاسخ را از فرستادن درخواست جدا کنید
سیاست هممبدأ خواندن پاسخها میان مبدأها را محدود میکند. جلوی فرستادن درخواست را نمیگیرد و جلوی آن را هم نمیگیرد که فرمی اعتبارنامههایی را که مرورگر دارد حمل کند. درخواست ساده، با نوع محتوای فرم یا GET ساده، بدون بررسی مقدماتی تحویل میشود؛ سپس CORS تصمیم میگیرد آیا اسکریپت فراخواننده میتواند پاسخ را بخواند. CSRF تماماً در سمت فرستادن زندگی میکند.
از این رو سرور به بررسی صریح برای عملیات تغییردهندهٔ وضعیت نیاز دارد. توکن همگامسازی وابسته به نشست، یا کوکی ارسال دوباره که در سرور مقایسه میشود، این حالت را پوشش میدهد؛ مقایسهٔ Origin یا Referer ارزش افزودن بهعنوان دروازهٔ دوم را دارد اما نه بهعنوان تنها دروازه، چون هر درخواست سرصفحه را حمل نمیکند و هر پروکسی آن را نگه نمیدارد. راهنمای OWASP برای پیشگیری از CSRF SameSite را دقیقاً به همین دلیل یکی از چند لایه میداند.
تصمیم بگیرید دروازهٔ شبکه واقعاً چه چیزی را اثبات میکند
فهرست مجاز خروجیهای VPN در برابر میزبان مدیریتی کنترل خوبی است و ادعای هویت ضعیفی. اثبات میکند درخواست از نشانیای آمده که VPN میدهد، که همهٔ افراد روی آن خروجی میتوانند در آن شریک باشند، و هیچ چیزی دربارهٔ اینکه کدام شخص یا دستگاه پشت آن است نمیگوید. آن را فیلتر ورود بدانید، نه احراز هویت.
آن را از بررسیهای سطح درخواست مستقل نگه دارید. اگر فهرست تنها چیز میان مهاجم و نقطهٔ پایانی تغییردهندهٔ وضعیت باشد، یک مسیر بدتنظیم، یک کلاینت split-tunnel یا یک لپتاپ قرضی کنترل را کاملاً برمیدارد.
ردهای بیرون از بازههای انتظار را هم ثبت کنید. هجوم آنها سودمندترین نشانه است که کسی مرزی را که تازه ساختید میکاود، و سکوت نشانهٔ آن است که فیلتر اصلاً دیده نمیشود.
کوکیها، ورود و مجوز را صریح نگه دارید
دامنهٔ کوکی بیشتر نتیجه را تعیین میکند. کوکی دامنهٔ والد به میزبان مدیریتی فرستاده میشود، پس تزریق اسکریپت در سایت عمومی میتواند با نشست یک مدیر عمل کند؛ کوکی فقط-میزبان نمیتواند. شکل فقط-میزبان را ترجیح دهید، ویژگی Secure را بیفزایید و پیشوند __Host- را جایی که پلتفرم پشتیبانی میکند به کار ببرید، چون آن پیشوند Secure، Path=/ و نبود ویژگی Domain را میخواهد. سرصفحهٔ پاسخ را بخوانید نه ظرف کوکی را: Set-Cookie: __Host-admin_session=...; Secure; Path=/; HttpOnly; SameSite=Lax، بدون ویژگی Domain. مرورگر کوکی __Host- را که Domain دارد دور میریزد، پس کوکیای که هنوز روی میزبانهای خواهر دیده میشود دلیل آن است که پیشوند هرگز اعمال نشده.
سپس مجوز را در سرور، برای هر درخواست، روی هر نقطهٔ پایانی مدیریتی نگه دارید، نه فقط هنگام ورود. درخواستی که از شبکهٔ مجاز میآید باز هم باید احراز و برای عملیاتی که میخواهد مجاز شود؛ نام میزبان یک کنشگر نیست. اگر برنامهٔ عمومی و مدیریتی جریان ورود یا انبار نشست را شریکاند، آن رابطه را بنویسید، چون کوتاهترین راه از یک ایراد در سایت عمومی به یک کنش مدیریتی است.
پس از جداسازی مرز را دوباره بررسی کنید
آزمونهای منفی را اجرا کنید، نه فقط مسیر خوشحال: فرم میانسایتی بدون توکن باید رد شود، توکن از نشست دیگر باید رد شود و هیچ GET نباید وضعیت را عوض کند. ویژگیهای کوکی را در ابزار توسعهدهنده بررسی کنید، تأیید کنید بررسی Origin روی درخواست ناهمخوان فعال میشود و میزبان مدیریتی را از بیرون بازهٔ VPN امتحان کنید تا فیلتر را در کار ببینید.
هیچیک از اینها ایراد XSS درون خود برنامهٔ مدیریتی را برنمیدارد. نام میزبان جدا یک مرز جداسازی سمت مرورگر با ارزش واقعی است و جایگزین جلوگیری از اجرای کد ناایمن یا محافظت از درخواست در سمت سرور نیست. پس از جداسازی فهرست کوتاهتر از آن است که به نظر میرسد: مبدأ متمایز، کوکیهای فقط-میزبان، توکن روی هر تغییر، فیلتر ورودی که بهعنوان هویت به آن اعتماد نمیکنید و مجوزی که برای هر درخواست تعیین میشود.