محافظت در برابر حملات Clickjacking با X-Frame-Options و CSP
آشنایی با حملات کلیکدزدی (Clickjacking) و بررسی دو روش اصلی محافظت در برابر آنها: هدر X-Frame-Options و سیاست امنیتی محتوا (CSP). با مثالهای عملی برای پیادهسازی.
تهدید clickjacking چیست و چرا باید جدی گرفته شود؟
clickjacking که با نامهای "کلیکدزدی" یا "UI redress attack" نیز شناخته میشود، یک تکنیک مخرب است که در آن مهاجم کاربر را فریب میدهد تا روی دکمهها، لینکها یا فرمهای یک سایت معتبر کلیک کند، در حالی که کاربر فکر میکند روی یک چیز دیگر کلیک میکند. این حمله معمولاً با استفاده از iframe و لایههای CSS شفاف انجام میشود.
فرض کنید کاربر وارد یک سایت بازی آنلاین شده و روی دکمه "شروع بازی" کلیک میکند، اما در واقع در حال تأیید تراکنش بانکی خود در iframe نامرئی از سایت بانک است. خطر اصلی clickjacking همین است: کاربر بدون آگاهی، اقدامات حساسی را در سایتهای معتبر انجام میدهد. این حملات میتوانند منجر به سرقت اطلاعات، انتقال غیرمجاز وجوه، انتشار پستهای ناخواسته در شبکههای اجتماعی یا حتی دسترسی به دوربین و میکروفون دستگاه کاربر شوند.
روش اول: محافظت با هدر X-Frame-Options
X-Frame-Options یک هدر HTTP است که به مرورگر دستور میدهد آیا اجازه دارد صفحه وب شما را در یک frame یا iframe نمایش دهد یا خیر. این هدر ساده اما مؤثر، اولین خط دفاعی در برابر clickjacking محسوب میشود.
این هدر سه مقدار اصلی میتواند داشته باشد:
- DENY: هیچ سایتی اجازه ندارد این صفحه را در frame بارگذاری کند. این امنترین گزینه است.
- SAMEORIGIN: فقط صفحاتی که از همان origin (دامنه، پروتکل و پورت) هستند میتوانند این صفحه را در frame نمایش دهند.
- ALLOW-FROM uri: صفحه فقط میتواند توسط frame از یک URI خاص نمایش داده شود (این مقدار در مرورگرهای مدرن پشتیبانی محدودی دارد).
مثال پیادهسازی X-Frame-Options در سمت سرور
در Apache، میتوانید در فایل .htaccess خط زیر را اضافه کنید:
Header always set X-Frame-Options "SAMEORIGIN"
در Nginx، در بخش سرور مربوطه در فایل پیکربندی:
add_header X-Frame-Options "SAMEORIGIN";
برای برنامههای Node.js با Express:
app.use(helmet.frameguard({ action: 'sameorigin' })); // با استفاده از Helmet.js
در PHP میتوان از تابع header استفاده کرد:
header('X-Frame-Options: SAMEORIGIN');
با تنظیم این هدر، اگر سایتی بخواهد صفحه شما را در iframe بارگذاری کند، مرورگر از نمایش آن جلوگیری میکند یا یک صفحه خالی/خطا نشان میدهد.
روش دوم و پیشرفتهتر: سیاست امنیتی محتوا (CSP)
با اینکه X-Frame-Options مفید است، اما محدودیتهایی دارد و در حال حاضر استاندارد منسوخشدهای محسوب میشود. راهکار مدرنتر و قدرتمندتر، استفاده از هدر Content-Security-Policy یا CSP است. CSP نه تنها در برابر clickjacking، بلکه در برابر انواع دیگری از حملات مانند XSS نیز محافظت میکند.
برای کنترل frameها در CSP، از دستور frame-ancestors استفاده میکنیم. این دستور مشخص میکند که چه سایتهایی میتوانند صفحه شما را در یک frame (مانند iframe، object، embed) بارگذاری کنند.
مثالهای عملی CSP برای کنترل frame
- ممنوعیت کامل بارگذاری در frame: Content-Security-Policy: frame-ancestors 'none';
این دستور معادل X-Frame-Options: DENY است. - اجازه فقط برای دامنه خودتان: Content-Security-Policy: frame-ancestors 'self';
این دستور معادل X-Frame-Options: SAMEORIGIN است. - اجازه برای چند دامنه خاص: Content-Security-Policy: frame-ancestors 'self' https://trusted-site.com https://another-trusted.example.com;
این قابلیتی است که X-Frame-Options به خوبی از آن پشتیبانی نمیکرد. - اجازه برای همه (غیرامن): Content-Security-Policy: frame-ancestors *;
این تنظیم محافظتی در برابر clickjacking ایجاد نمیکند و فقط برای مواقع خاص توصیه میشود.
پیادهسازی CSP در عمل
مانند X-Frame-Options، CSP نیز یک هدر HTTP است. در Nginx:
add_header Content-Security-Policy "frame-ancestors 'self';";
در Apache:
Header set Content-Security-Policy "frame-ancestors 'self'"
در برنامههای Express.js با Helmet:
app.use(helmet.contentSecurityPolicy({
directives: {
frameAncestors: ["'self'"],
},
}));
مقایسه X-Frame-Options و CSP: کدام را انتخاب کنیم؟
اگر پشتیبانی از مرورگرهای قدیمی (مانند Internet Explorer) برای شما مهم است، باید از هر دو هدر به صورت همزمان استفاده کنید. زیرا IE از دستور frame-ancestors در CSP پشتیبانی نمیکند. در این حالت، مرورگرهای مدرن از CSP و مرورگرهای قدیمی از X-Frame-Options پیروی میکنند.
تنظیم همزمان در Nginx:
add_header X-Frame-Options "SAMEORIGIN";
add_header Content-Security-Policy "frame-ancestors 'self';";
اما برای پروژههای مدرن که نیاز به پشتیبانی از IE ندارند، توصیه میشود فقط از CSP استفاده کنید. CSP انعطافپذیرتر است و کنترل دقیقتری ارائه میدهد. مزیت دیگر CSP این است که میتوانید آن را از طریق یک متا تگ در HTML نیز اعمال کنید، اگر دسترسی به تنظیمات هدر سرور ندارید:
<meta http-equiv="Content-Security-Policy" content="frame-ancestors 'self'">
البته تنظیم از طریق هدر HTTP روش ارجح و امنتر است.
آزمایش و عیبیابی محافظت در برابر clickjacking
پس از پیادهسازی، باید مطمئن شوید که تنظیمات به درستی کار میکنند. چند روش برای تست وجود دارد:
- بررسی هدرها: از ابزارهای Developer Tools مرورگر (تب Network) استفاده کنید و پاسخ سرور را بررسی نمایید. باید هدر X-Frame-Options یا CSP (یا هر دو) را در آن ببینید.
- ایجاد یک صفحه تست ساده: یک فایل HTML در یک دامنه دیگر (یا حتی لوکالhost) ایجاد کنید که سعی کند صفحه مورد نظر شما را در iframe بارگذاری کند. اگر تنظیمات درست باشد، صفحه بارگذاری نخواهد شد.
- استفاده از ابزارهای آنلاین: ابزارهایی مانند "SecurityHeaders.com" میتوانند هدرهای امنیتی سایت شما را تحلیل و نمرهدهی کنند.
- تست نفوذ: میتوانید از ابزارهای تست نفوذ مانند Burp Suite یا OWASP ZAP برای شبیهسازی حمله clickjacking استفاده کنید.
یک نکته مهم: اگر سایت شما طراحی شده تا در iframe سایتهای خاصی (مثلاً یک پلتفرم خاص) نمایش داده شود، حتماً باید آن دامنهها را در تنظیمات frame-ancestors (CSP) یا با مقدار ALLOW-FROM (در صورت استفاده از X-Frame-Options و پشتیبانی مرورگر) مجاز کنید. در غیر این صورت عملکرد سایت شما در آن بستر مختل میشود.
سخن پایانی و بهترین شیوهها
حملات clickjacking یک تهدید واقعی و کمهزینه برای مهاجمان هستند. محافظت در برابر آنها نه تنها امنیت کاربران شما را افزایش میدهد، بلکه میتواند به عنوان یک سیگنال مثبت برای موتورهای جستجو و ممیزیهای امنیتی در نظر گرفته شود. به عنوان یک متخصص سئو و امنیت، توصیه میکنم:
- حداقل از هدر X-Frame-Options: SAMEORIGIN استفاده کنید. این یک تنظیم سریع و مؤثر است.
- در بلندمدت، پیادهسازی یک سیاست CSP کامل را در برنامه خود داشته باشید که شامل دستور frame-ancestors باشد.
- همیشه پس از اعمال تغییرات، تستهای امنیتی را انجام دهید.
- از ابزارهای گزارشگیری CSP (با استفاده از دستور report-uri) برای شناسایی تلاشهای شکست خورده بارگذاری frame استفاده کنید تا از حملات احتمالی آگاه شوید.
- این تنظیمات را در چکلیست امنیتی و سئو فنی خود قرار دهید و هنگام راهاندازی هر سایت جدید یا انتقال سرور، آنها را بررسی نمایید.
با این اقدامات ساده اما حیاتی، لایهای مهم از امنیت را برای کاربران و کسبوکار خود اضافه میکنید و از اعتبار سایت در برابر سوءاستفاده محافظت مینمایید.