پرش به محتوای اصلی
آسیب‌پذیری‌های سایت

Clickjacking چیست؟ بررسی حمله کلیک‌جکینگ و روش‌های جلوگیری از آن

Clickjacking یا کلیک‌جکینگ نوعی حمله UI Redressing است که در آن کاربر بدون اطلاع روی یک عنصر واقعی از سایت دیگری کلیک می‌کند و ممکن است عملیاتی با Session معتبر خودش انجام دهد. این حمله معمولاً به قابلیت Frame شدن صفحات حساس در iframe وابسته است. استفاده از CSP frame-ancestors، X-Frame-Options، تنظیم مناسب SameSite Cookie و تأیید مجدد عملیات حساس از مهم‌ترین روش‌های جلوگیری از Clickjacking هستند. در طراحی امن، هر صفحه باید مشخص کند دقیقاً چه Originهایی اجازه دارند آن را داخل Frame نمایش دهند.

تیم امنیت رخنه‌کاو ۳۷ دقیقه مطالعه انتشار:

Clickjacking یا «کلیک‌جکینگ» نوعی حمله رابط کاربری یا UI Redressing است که در آن مهاجم کاربر را فریب می‌دهد تا روی یک عنصر واقعی از سایت دیگری کلیک کند؛ در حالی که کاربر تصور می‌کند در حال تعامل با صفحه یا دکمه‌ای کاملاً متفاوت است. این حمله معمولاً با قرار دادن سایت هدف داخل یک iframe و پوشاندن یا هم‌تراز کردن آن با عناصر ظاهری صفحه مهاجم انجام می‌شود.

اگر کاربر از قبل در سایت هدف Login کرده باشد، کلیک او ممکن است با Session واقعی خودش ثبت شود و عملیاتی مانند تغییر تنظیمات، تأیید درخواست یا فعال‌سازی یک قابلیت را انجام دهد. دفاع اصلی در برابر Clickjacking جلوگیری یا محدود کردن Framing با Content-Security-Policy: frame-ancestors و در صورت نیاز X-Frame-Options است. تنظیم SameSite برای Cookieهای Session نیز می‌تواند یک لایه دفاعی اضافی ایجاد کند.

Clickjacking از آن دسته آسیب‌پذیری‌هایی است که ممکن است در نگاه اول ساده به نظر برسد؛ اما علت خطرناک بودن آن این است که مهاجم الزاماً نیازی ندارد Authentication کاربر را بشکند، Password او را بداند یا مستقیماً به Session Token دسترسی پیدا کند. مهاجم تلاش می‌کند خود کاربر را به ابزاری برای انجام عملیات تبدیل کند.

به همین دلیل امنیت رابط کاربری در برنامه‌های وب فقط مسئله طراحی ظاهری نیست. Browser باید بداند چه وب‌سایت‌هایی مجاز هستند محتوای یک سایت را داخل Frame، iframe، object یا embed نمایش دهند.

در این مقاله رخنه‌کاو بررسی می‌کنیم Clickjacking چیست، حمله کلیک‌جکینگ چگونه کار می‌کند، چه شرایطی برای موفقیت آن لازم است، چه تفاوتی با CSRF و XSS دارد و چگونه می‌توان با CSP، X-Frame-Options، SameSite، طراحی امن عملیات حساس و سایر کنترل‌های دفاعی از آن جلوگیری کرد.

Clickjacking چیست؟

Clickjacking ترکیبی از دو واژه Click و Hijacking است و به شرایطی اشاره می‌کند که مهاجم «هدف واقعی کلیک کاربر» را پنهان یا تغییر می‌دهد.

کاربر چیزی را می‌بیند، اما روی چیز دیگری کلیک می‌کند.

فرض کنید کاربر وارد یک سایت معتبر شده و Session فعال دارد.

مهاجم صفحه‌ای در Domain خودش ایجاد می‌کند و سایت معتبر را داخل یک iframe قرار می‌دهد.

سپس با استفاده از چیدمان ظاهری صفحه، iframe یا قسمت حساس آن را روی یک Button ساختگی قرار می‌دهد.

کاربر تصور می‌کند روی دکمه‌ای مانند:

«مشاهده جایزه»

«پخش ویدئو»

«ادامه»

یا یک کنترل ظاهراً بی‌خطر کلیک می‌کند.

اما کلیک واقعی روی Button داخل سایت هدف انجام می‌شود.

MDN Clickjacking را حمله‌ای تعریف می‌کند که در آن مهاجم سایت هدف را در یک iframe داخل سایت Decoy قرار می‌دهد و از لایه‌بندی رابط کاربری استفاده می‌کند تا کاربر روی کنترل سایت هدف تعامل داشته باشد، بدون اینکه متوجه هدف واقعی کلیک شود. اگر User در سایت هدف Login باشد، درخواست می‌تواند با Credentialهای واقعی همان User اجرا شود.

چرا Clickjacking یک حمله رابط کاربری محسوب می‌شود؟

در بسیاری از حملات وب مهاجم مستقیماً با Server یا Code آسیب‌پذیر تعامل دارد.

مثلاً در SQL Injection مشکل در پردازش Query است.

در XSS مشکل در اجرای Script کنترل‌نشده در Context سایت است.

اما در Clickjacking، مهاجم در بسیاری از سناریوها از Featureهای قانونی Browser استفاده می‌کند:

iframe

CSS

Opacity

Positioning

Layering

User Interaction

مشکل اصلی زمانی ایجاد می‌شود که سایت هدف اجازه می‌دهد صفحه حساس آن توسط یک Origin غیرمجاز Frame شود.

به همین دلیل Clickjacking در خانواده حملات UI Redressing قرار می‌گیرد.

UI Redressing یعنی تغییر ادراک کاربر نسبت به رابطی که واقعاً با آن تعامل دارد. حمله Clickjacking چگونه کار می‌کند؟

حمله Clickjacking چگونه کار می‌کند؟

برای درک سازوکار حمله، بهتر است یک سناریوی مفهومی را بررسی کنیم.

فرض کنید سایتی دارای صفحه‌ای برای تغییر یک تنظیم مهم است.

کاربر از قبل Login کرده و Session Cookie معتبر دارد.

مرحله اول: مهاجم یک صفحه کنترل‌شده ایجاد می‌کند

این صفحه می‌تواند ظاهراً کاملاً معمولی باشد.

مثلاً یک صفحه سرگرمی، Quiz، Button یا Content جذاب.

مرحله دوم: سایت هدف داخل iframe قرار می‌گیرد

اگر سایت هدف هیچ محدودیت مناسبی برای Framing اعمال نکرده باشد، Browser ممکن است اجازه دهد آن صفحه داخل iframe مهاجم نمایش داده شود.

مرحله سوم: iframe روی عنصر ساختگی قرار می‌گیرد

مهاجم می‌تواند با CSS موقعیت iframe را با یک Button یا بخش خاصی از صفحه خودش هم‌تراز کند.

iframe ممکن است بسیار شفاف باشد.

کاربر صفحه مهاجم را می‌بیند اما عنصر سایت هدف روی نقطه کلیک قرار گرفته است.

مرحله چهارم: کاربر کلیک می‌کند

User تصور می‌کند با سایت مهاجم تعامل دارد.

اما Browser Click را به کنترل واقعی داخل iframe می‌رساند.

مرحله پنجم: سایت هدف درخواست را معتبر تلقی می‌کند

اگر User در سایت هدف Session معتبر داشته باشد و Action به تأیید اضافی نیاز نداشته باشد، درخواست ممکن است مانند یک Click عادی User پردازش شود.

این ویژگی Clickjacking را خطرناک می‌کند:

مهاجم Credential را لزوماً نمی‌دزدد.

از Context احراز هویت‌شده خود User استفاده می‌کند.

چرا iframe در Clickjacking اهمیت دارد؟

iframe یکی از قابلیت‌های استاندارد HTML است که اجازه می‌دهد یک Document دیگر داخل صفحه فعلی نمایش داده شود.

iframe به‌خودی‌خود آسیب‌پذیری نیست.

کاربردهای قانونی زیادی دارد:

پخش Video

Widget

Payment Component

Map

Dashboard

Embed Content

Preview

اما اگر یک صفحه حساس بدون محدودیت قابل Frame شدن باشد، مهاجم می‌تواند آن را داخل Origin خودش Embed کند.

OWASP و MDN هر دو تأکید می‌کنند دفاع اصلی در برابر Clickjacking کنترل این موضوع است که چه Originهایی اجازه دارند صفحه را Frame کنند.

Clickjacking چه شرایطی برای موفقیت نیاز دارد؟

هر سایتی که داخل iframe Load شود الزاماً در برابر Clickjacking آسیب‌پذیر نیست.

چند شرط معمولاً باید کنار یکدیگر قرار بگیرند.

صفحه هدف قابل Frame شدن باشد

اگر Browser به دلیل CSP frame-ancestors یا X-Frame-Options از Load شدن صفحه داخل Frame جلوگیری کند، بخش اصلی Attack Flow از کار می‌افتد.

صفحه دارای Action قابل تعامل باشد

صرفاً Frame شدن صفحه Static الزاماً Risk مهمی ایجاد نمی‌کند.

Clickjacking زمانی جدی‌تر می‌شود که صفحه دارای Button، Link، Checkbox یا عملیات Sensitive باشد.

کاربر Context معتبر داشته باشد

در بسیاری از Scenarioها User باید از قبل Login باشد.

اگر Session در iframe ارسال شود، Server ممکن است User را همان کاربر احراز هویت‌شده تشخیص دهد.

عملیات حساس به تأیید اضافه نیاز نداشته باشد

اگر Action بسیار حساس نیازمند Password مجدد، MFA، Confirmation واضح یا Step-up Authentication باشد، یک Click ساده ممکن است کافی نباشد.

آیا Same-Origin Policy جلوی Clickjacking را نمی‌گیرد؟

Same-Origin Policy یکی از پایه‌های امنیت Browser است، اما به‌تنهایی Clickjacking را متوقف نمی‌کند.

Same-Origin Policy معمولاً اجازه نمی‌دهد Script سایت مهاجم محتوای iframe متعلق به Origin دیگری را آزادانه بخواند یا DOM آن را Manipulate کند.

اما Clickjacking الزاماً نیازمند خواندن DOM سایت هدف نیست.

مهاجم ممکن است فقط صفحه را Frame کند و User را وادار کند روی محل خاصی کلیک کند.

این تفاوت بسیار مهم است.

مرورگر می‌تواند بگوید:

«Script سایت A اجازه خواندن DOM سایت B را ندارد.»

اما اگر سایت B Framing را ممنوع نکرده باشد، همچنان ممکن است:

«سایت A اجازه نمایش B داخل iframe را داشته باشد.»

frame-ancestors دقیقاً برای کنترل همین رابطه طراحی شده است.

W3C مشخص می‌کند frame-ancestors Originهایی را محدود می‌کند که می‌توانند Resource را از طریق frame، iframe، object یا embed در خود قرار دهند و هدف آن کاهش UI Redressing است.

تأثیر Clickjacking چیست؟

Impact کلیک‌جکینگ کاملاً به قابلیت‌هایی بستگی دارد که سایت هدف در دسترس User قرار داده است.

در یک سایت ساده شاید Impact بسیار محدود باشد.

در یک Application حساس ممکن است جدی‌تر باشد.

سناریوهای ممکن می‌توانند شامل:

تغییر بعضی تنظیمات حساب

فعال یا غیرفعال کردن یک Feature

ارسال Action از طرف User

تغییر Preference

تأیید یک Operation

تعامل ناخواسته با Permissionها

انجام عملیات داخل Dashboard

باشند.

شدت Risk باید براساس Application واقعی ارزیابی شود، نه صرفاً وجود امکان Frame شدن.

صفحه‌ای که فقط یک مقاله عمومی نمایش می‌دهد Risk متفاوتی با صفحه‌ای دارد که یک Action مهم مالی یا Account Management انجام می‌دهد.

Clickjacking با CSRF چه تفاوتی دارد؟

Clickjacking و Cross-Site Request Forgery یا CSRF شباهت‌هایی دارند.

در هر دو Attack، ممکن است از Session معتبر User برای انجام Action استفاده شود.

اما Mechanism متفاوت است.

ویژگیClickjackingCSRF
نیاز به تعامل Userمعمولاً بلهممکن است نیاز کمتری داشته باشد
تمرکز اصلیرابط کاربری و Clickارسال Request از Origin دیگر
استفاده از iframeرایجالزامی نیست
سوءاستفاده از Sessionممکن استمعمولاً
دفاع مهمframe-ancestorsCSRF Token / SameSite / Origin checks
ماهیتUI RedressingRequest Forgery

در Clickjacking، مهاجم User را فریب می‌دهد تا خودش روی UI واقعی کلیک کند.

در CSRF مهاجم معمولاً تلاش می‌کند Browser را مجبور کند Request ناخواسته‌ای برای سایت هدف بفرستد.

این دو دفاع مشترک‌هایی مانند SameSite Cookie دارند، اما جایگزین یکدیگر نیستند.

آیا CSRF Token جلوی Clickjacking را می‌گیرد؟

نه لزوماً.

این یکی از اشتباهات رایج در طراحی امنیتی است.

CSRF Token برای اثبات این موضوع طراحی شده که Request از Workflow معتبر Application آمده است.

اما در Clickjacking ممکن است User مستقیماً روی فرم واقعی سایت هدف کلیک کند.

در این حالت Token معتبر خودش داخل همان صفحه وجود دارد.

User واقعاً با Page هدف Interaction انجام داده؛ فقط نمی‌داند چه چیزی را Click کرده است.

بنابراین CSRF Protection جایگزین Anti-framing نیست.

به همان ترتیب frame-ancestors نیز جایگزین CSRF Protection نیست.

Defense in Depth یعنی هر Risk با Control مناسب خودش پوشش داده شود.

Clickjacking با XSS چه تفاوتی دارد؟

Cross-Site Scripting یا XSS به مهاجم اجازه می‌دهد Script غیرمجاز را در Context سایت هدف اجرا کند.

Clickjacking چنین قابلیتی را الزامی نمی‌کند.

در XSS مهاجم ممکن است بتواند:

DOM را Manipulate کند،

Data بخواند،

Request ارسال کند،

Session Context را Abuse کند.

در Clickjacking تمرکز بر Manipulation ادراک User است.

بنابراین ممکن است Application هیچ XSS نداشته باشد اما همچنان Clickjacking Risk داشته باشد.

Likejacking چیست؟

اصطلاح Likejacking به نوعی از Clickjacking گفته می‌شود که User فریب داده می‌شود تا روی Control مربوط به Like، Follow یا تعامل اجتماعی کلیک کند.

اصل Attack همان است:

Control واقعی پنهان می‌شود.

User روی چیزی کلیک می‌کند که تصور می‌کند هدف دیگری دارد.

OWASP نیز Clickjacking را در گذشته در سناریوهای مرتبط با سوءاستفاده از تعاملات اجتماعی توضیح داده است.

UI Redressing چیست؟

UI Redressing اصطلاح گسترده‌تری نسبت به Clickjacking است.

در UI Redressing مهاجم ظاهر Interface را طوری تغییر می‌دهد که User Interpretation اشتباهی از Action واقعی داشته باشد.

Clickjacking یکی از شناخته‌شده‌ترین شکل‌های آن است.

اصل دفاعی مهم این است:

هر جا Browser اجازه Embed شدن Resource حساس را می‌دهد، باید مشخص باشد چه Originهایی واقعاً به این قابلیت نیاز دارند.

بهترین روش جلوگیری از Clickjacking چیست؟

امروزه مهم‌ترین دفاع، استفاده از CSP frame-ancestors است.

برای سازگاری دفاعی بیشتر ممکن است در کنار آن X-Frame-Options نیز استفاده شود.

OWASP سه Mechanism اصلی را برای دفاع مطرح می‌کند:

  1. جلوگیری از Framing با frame-ancestors یا X-Frame-Options
  2. محدود کردن Cookieهای Cross-site با SameSite
  3. استفاده از Frame-busting JavaScript برای Browserهای قدیمی یا شرایط خاص

OWASP توصیه می‌کند در صورت امکان بیش از یک لایه دفاعی استفاده شود. CSP frame-ancestors چیست؟

CSP frame-ancestors چیست؟

Content Security Policy یا CSP مجموعه‌ای از Policyهای امنیتی است که از طریق HTTP Response Header به Browser اعلام می‌شوند.

یکی از Directiveهای مهم آن:

frame-ancestors

است.

این Directive مشخص می‌کند کدام Parent Originها مجاز هستند Document را Frame کنند.

MDN می‌گوید frame-ancestors Parentهای معتبر برای Embed کردن صفحه از طریق frame، iframe، object یا embed را مشخص می‌کند. این قابلیت از ژانویه ۲۰۱۸ به‌صورت گسترده در Browserهای مدرن در دسترس بوده است.

جلوگیری کامل از Framing

اگر سایت هیچ نیازی به Embed شدن ندارد:

Content-Security-Policy: frame-ancestors 'none';

این Policy به Browser می‌گوید هیچ Originی اجازه Frame کردن صفحه را ندارد.

OWASP و MDN این گزینه را زمانی توصیه می‌کنند که نیاز واقعی به Framing وجود ندارد.

فقط همان Origin

اگر صفحه باید فقط توسط صفحات همان Origin Embed شود:

Content-Security-Policy: frame-ancestors 'self';

در این حالت Cross-origin Framing Block می‌شود.

اجازه به Originهای مشخص

یکی از مزیت‌های اصلی CSP نسبت به X-Frame-Options انعطاف بیشتر آن است.

می‌توان Originهای مورداعتماد مشخصی را مجاز کرد.

اما Allowlist باید حداقلی باشد.

هر Domain اضافه‌شده به frame-ancestors بخشی از Trust Model شما می‌شود.

frame-ancestors با frame-src چه تفاوتی دارد؟

این دو Directive اغلب با یکدیگر اشتباه گرفته می‌شوند.

frame-ancestors می‌گوید:

«چه کسی اجازه دارد من را داخل Frame نمایش دهد؟»

اما frame-src مشخص می‌کند:

«صفحه من از چه Sourceهایی اجازه دارد Frame Load کند؟»

MDN صراحتاً این تفاوت را توضیح می‌دهد.

برای جلوگیری از Clickjacking صفحه هدف، Directive اصلی frame-ancestors است.

آیا default-src 'none' جلوی Framing را می‌گیرد؟

این نکته بسیار مهم است.

خیر.

frame-ancestors به default-src Fallback نمی‌کند.

یعنی حتی اگر CSP شما چنین Policy سخت‌گیرانه‌ای داشته باشد:

default-src 'none'

اما frame-ancestors مشخص نشده باشد، نباید تصور کنید Anti-clickjacking Policy نیز خودکار اعمال شده است.

W3C صراحتاً مشخص می‌کند frame-ancestors از default-src مقدار پیش‌فرض نمی‌گیرد.

بنابراین این Directive باید آگاهانه تعریف شود.

آیا frame-ancestors را می‌توان در meta نوشت؟

خیر.

این یکی از اشتباهات رایج است.

frame-ancestors باید در HTTP Response Header ارسال شود.

W3C مشخص می‌کند این Directive وقتی از طریق meta تعریف شود باید نادیده گرفته شود. OWASP نیز همین موضوع را در راهنمای دفاع Clickjacking ذکر می‌کند.

بنابراین این روش مناسب نیست:

قرار دادن یک CSP Meta Tag و انتظار Anti-framing Protection.

Policy باید در Response Header باشد. X-Frame-Options چیست؟ DENY و SAMEORIGIN چه تفاوتی دارند؟

X-Frame-Options چیست؟

X-Frame-Options یک HTTP Response Header قدیمی‌تر برای کنترل Framing است.

دو مقدار اصلی قابل استفاده در Browserهای مدرن:

DENY

و:

SAMEORIGIN

هستند.

DENY

X-Frame-Options: DENY

هیچ صفحه‌ای، حتی از همان Origin، اجازه Frame کردن Document را ندارد.

SAMEORIGIN

X-Frame-Options: SAMEORIGIN

فقط Same-origin Framing مجاز است.

MDN توضیح می‌دهد اگر هیچ X-Frame-Options یا Mechanism مشابهی مانند frame-ancestors ارسال نشود، Browser به‌طور پیش‌فرض می‌تواند اجازه دهد Siteهای دیگر Document را Frame کنند.

ALLOW-FROM چیست و چرا نباید روی آن تکیه کرد؟

نسخه‌های قدیمی X-Frame-Options مقدار دیگری به نام:

ALLOW-FROM

داشتند.

هدف این بود که یک URI مشخص برای Framing مجاز شود.

اما این Directive منسوخ شده و Browserهای مدرن از آن به شکل قابل اتکا پشتیبانی نمی‌کنند.

OWASP هشدار می‌دهد وابستگی به ALLOW-FROM می‌تواند باعث شود در Browserی که Directive را نمی‌شناسد عملاً Anti-clickjacking Protection وجود نداشته باشد.

اگر Allowlist چند Origin نیاز دارید، از CSP frame-ancestors استفاده کنید.

CSP frame-ancestors بهتر است یا X-Frame-Options؟

برای Web Application مدرن، frame-ancestors گزینه انعطاف‌پذیرتر است.

قابلیتframe-ancestorsX-Frame-Options
جلوگیری کامل از Frameبلهبله
Same-origin onlyبلهبله
Allowlist چند Originبلهخیر
روش مدرنبلهLegacy
بخشی از CSPبلهخیر
استفاده برای سازگاری قدیمیکمتر لازممفید

OWASP Content Security Policy Cheat Sheet می‌گوید X-Frame-Options برای این هدف توسط CSP frame-ancestors منسوخ شده است.

با این حال OWASP و MDN همچنان استفاده همزمان از هر دو Header را در بعضی Deploymentها برای Defense in Depth و Compatibility قدیمی مطرح می‌کنند. Browserهایی که frame-ancestors را پشتیبانی می‌کنند، هنگام وجود Policy enforce شده CSP، X-Frame-Options را نادیده می‌گیرند. SameSite Cookie چه کمکی به جلوگیری از Clickjacking می‌کند؟

Clickjacking در بسیاری از Scenarioها به این موضوع وابسته است که User هنگام Load شدن سایت هدف داخل iframe همچنان Logged-in باشد.

SameSite Attribute روی Cookie مشخص می‌کند Cookie در چه Cross-site Contextهایی ارسال شود.

اگر Session Cookie با Policy مناسب SameSite=Lax یا SameSite=Strict تنظیم شده باشد، بعضی Requestهای Cross-site و Embedded Contextها Cookie Authentication را دریافت نمی‌کنند.

در نتیجه iframe ممکن است سایت را به‌صورت Logged-out ببیند.

MDN این روش را یک Mitigation اضافی و جزئی می‌داند و توصیه می‌کند Session Cookieها در صورت سازگاری با نیاز Application از Lax یا Strict استفاده کنند.

چرا SameSite جایگزین frame-ancestors نیست؟

چون مسئله اصلی متفاوت است.

frame-ancestors می‌گوید:

«چه کسی اجازه دارد این صفحه را Embed کند؟»

SameSite Cookie می‌گوید:

«Cookie در چه Cross-site Contextی ارسال شود؟»

حتی اگر User داخل iframe Login نباشد، ممکن است بعضی صفحه‌های حساس یا UI عمومی همچنان قابل سوءاستفاده باشند.

از طرف دیگر بعضی Applicationها به دلیل Workflow خاص به Cookie Cross-site نیاز دارند.

بنابراین SameSite باید یک Defense Layer اضافه باشد، نه تنها دفاع.

Frame Busting چیست؟

قبل از رواج Headerهای استاندارد، بسیاری از سایت‌ها از JavaScript برای تشخیص Frame شدن صفحه استفاده می‌کردند.

این Scriptها معمولاً بررسی می‌کردند آیا:

window.top

با:

window.self

یکسان است یا نه.

اگر صفحه داخل Frame بود، تلاش می‌کردند از Frame خارج شوند.

این روش Frame Busting نامیده می‌شود.

OWASP همچنان نمونه‌ای برای Browserهای Legacy ارائه می‌کند، اما دفاع استاندارد و مطمئن‌تر استفاده از Headerهای Browser-enforced مانند CSP و X-Frame-Options است.

چرا JavaScript Frame Busting به‌تنهایی کافی نیست؟

JavaScript تحت شرایط مختلف ممکن است:

Block شود،

غیرفعال باشد،

با Policyهای Frame محدود شود،

یا به دلیل Race/Rendering Behavior نتیجه مورد انتظار را ندهد.

Security Controlی که Browser قبل از Render اعمال کند، معمولاً قابل اتکاتر از Scriptی است که پس از Load شدن Document اجرا می‌شود.

بنابراین:

CSP → Control اصلی

X-Frame-Options → Compatibility / Defense in Depth

Frame Busting → Legacy / Supplemental

مدل منطقی‌تری است.

آیا iframe sandbox جلوی Clickjacking را می‌گیرد؟

sandbox Attribute برای محدود کردن قابلیت‌های Contentی که شما داخل iframe خودتان Load می‌کنید بسیار مفید است.

OWASP HTML5 Security Cheat Sheet توصیه می‌کند برای Content غیرقابل اعتماد داخل iframe از sandbox استفاده شود.

اما این موضوع با جلوگیری از Frame شدن خود سایت شما متفاوت است.

اگر هدف این است که Site مهاجم نتواند Page شما را Frame کند، باید Anti-framing Header روی Response خودتان تنظیم کنید.

iframe sandbox بیشتر برای این سؤال است:

«من Page دیگری را داخل iframe قرار داده‌ام؛ آن Page چه Capabilityهایی داشته باشد؟»

نه:

«چه کسی اجازه دارد من را iframe کند؟»

آیا Confirmation برای عملیات حساس مفید است؟

بله، اما نباید دفاع اصلی باشد.

اگر Action بسیار Sensitive است، Confirmation واضح و مستقل می‌تواند Risk را کاهش دهد.

برای مثال:

نمایش اطلاعات دقیق Operation

درخواست Password مجدد

MFA

Step-up Authentication

Confirmation Screen

OWASP حتی در شرایطی که Content باید Frameable باقی بماند، window.confirm() را به‌عنوان یک Mitigation خاص مطرح کرده است، هرچند X-Frame-Options یا Frame-breaking را Fail-safeتر می‌داند.

برای عملیات بسیار حساس بهتر است User دقیقاً بداند چه کاری را تأیید می‌کند.

Step-up Authentication چیست؟

Step-up Authentication یعنی User با اینکه قبلاً Login کرده است، برای عملیات حساس دوباره سطح بالاتری از Authentication ارائه کند.

مثلاً:

وارد کردن Password

MFA Code

Security Key

Biometric Confirmation در Context مناسب

اگر یک Click ناخواسته به‌تنهایی نتواند Operation Critical را تکمیل کند، Impact کلیک‌جکینگ کاهش پیدا می‌کند.

البته این Control جای Anti-framing را نمی‌گیرد.

آیا تمام صفحات سایت باید Framing را Block کنند؟

در بسیاری از سایت‌ها ساده‌ترین Policy این است که کل Site Framing را Block کند.

اما همیشه ممکن نیست.

بعضی محصولات عمداً نیاز دارند Embed شوند.

مثلاً:

Widget

Player

Payment Component

Partner Portal

Dashboard Embed

در این صورت frame-ancestors 'none' مناسب نیست.

باید مشخص شود کدام Originها واقعاً مجاز هستند.

اصل Least Privilege را می‌توان اینجا هم اعمال کرد:

به‌جای Allow کردن همه Originها، فقط Hostهای موردنیاز را Allow کنید.

Policy متفاوت برای صفحات مختلف

ممکن است یک Site بخشی Public و Embeddable داشته باشد و بخش Account نباید Frame شود.

برای مثال:

/embed/video/ → Partnerها اجازه Frame دارند.

/account/ → هیچ Origin خارجی اجازه Frame ندارد.

/admin/ → فقط Same-origin.

CSP امکان Policy دقیق‌تری نسبت به X-Frame-Options ایجاد می‌کند.

در چنین معماری‌ای Deployment Header باید براساس Route طراحی شود.

آیا فقط Login Page را باید محافظت کرد؟

خیر.

Clickjacking Risk محدود به Login نیست.

در واقع صفحه Login اغلب هدف اصلی نیست.

صفحه مهم‌تر ممکن است:

Settings

Payment

Account

Permissions

Admin

Delete

Subscription

Profile

باشد.

تمام HTML Responseهای Interactive باید براساس نیاز Framing بررسی شوند.

OWASP توصیه می‌کند X-Frame-Options برای تمام Responseهای HTML موردنیاز اعمال شود، نه فقط یک صفحه خاص.

Clickjacking در WordPress

سایت WordPress نیز یک Web Application است و می‌تواند دارای Pageهایی باشد که نباید توسط Originهای غیرمجاز Frame شوند.

WordPress Core تابعی با نام:

send_frame_options_header()

دارد.

مستندات رسمی WordPress نشان می‌دهد نسخه فعلی این Function دو Header زیر را ارسال می‌کند:

X-Frame-Options: SAMEORIGIN

و:

Content-Security-Policy: frame-ancestors 'self'

هدف Function نیز محدود کردن Render صفحات به Same-origin iframeها است.

WordPress Customizer نیز Security Headerهای مربوط به Framing را مدیریت می‌کند تا Preview Frontend بتواند در Context موردنیاز Load شود.

با این حال مدیر سایت نباید صرفاً فرض کند تمام Responseهای سایت WordPress تحت هر Configurationی Header درست دارند.

Caching Layer، CDN، Reverse Proxy، Web Server، افزونه، Headless Architecture و Custom Endpoint می‌توانند رفتار نهایی Response را تغییر دهند.

به همین دلیل باید HTTP Response واقعی Production بررسی شود.

Clickjacking در WooCommerce

در فروشگاه WooCommerce بخش‌های حساس متعددی وجود دارند:

My Account

Checkout

Payment Flow

Order Action

Subscription Management

Wallet Plugin

Coupon System

Custom Dashboard

اگر Plugin یا Custom Endpoint صفحه‌ای را بدون Anti-framing Policy ارائه کند، لازم است Risk آن بررسی شود.

خصوصاً اگر Page دارای Action حساس باشد.

همچنین باید Payment Providerها را در نظر گرفت.

بعضی Gatewayها عمداً از iframe استفاده می‌کنند.

در این حالت نباید بدون بررسی یک Policy سراسری اعمال کرد که Integration را بشکند.

ابتدا مشخص کنید:

چه Pageهایی باید Frame شوند؟

توسط چه Originهایی؟

سپس Allowlist محدود طراحی کنید.

Headless WordPress و iframe

در Headless Architecture ممکن است Frontend و Backend Origin متفاوت داشته باشند.

اما فراموش نکنیم CORS و Framing دو موضوع جدا هستند.

CORS مشخص می‌کند JavaScript از یک Origin چگونه می‌تواند Resource Origin دیگری را بخواند.

frame-ancestors مشخص می‌کند چه Originهایی می‌توانند Document را Frame کنند.

تنظیم CORS به‌تنهایی Clickjacking را حل نمی‌کند.

اشتباه رایج: استفاده از CORS برای جلوگیری از Clickjacking

این یکی از سوءبرداشت‌های پرتکرار است.

CORS Anti-clickjacking Mechanism نیست.

ممکن است Application CORS بسیار سخت‌گیرانه‌ای داشته باشد، اما همچنان Page داخل iframe خارجی Load شود.

Control درست:

CSP frame-ancestors

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

X-Frame-Options

است.

اشتباه رایج: X-Frame-Options داخل meta

این روش کار نمی‌کند.

OWASP صراحتاً می‌گوید Meta Tag برای X-Frame-Options معتبر نیست.

این Header باید HTTP Response Header باشد.

یعنی چیزی شبیه تنظیم HTML Meta Tag نباید به‌عنوان راهکار Anti-clickjacking در نظر گرفته شود.

اشتباه رایج: frame-ancestors داخل meta

این مورد نیز کار نمی‌کند.

طبق استاندارد CSP، frame-ancestors در Policy تعریف‌شده از طریق meta نادیده گرفته می‌شود.

Header باید قبل از Render صفحه توسط Browser قابل دریافت باشد.

اشتباه رایج: استفاده از ALLOW-FROM

ALLOW-FROM منسوخ شده است.

برای Allow کردن Domainهای خاص از frame-ancestors استفاده کنید.

اشتباه رایج: اعتماد کامل به SameSite

SameSite می‌تواند Attack Surface را کاهش دهد اما Anti-framing Header نیست.

ممکن است:

Cookie خاصی SameSite=None باشد،

Application بدون Login Action داشته باشد،

یا Workflow دیگری Clickjacking Risk داشته باشد.

Defense اصلی را حذف نکنید.

اشتباه رایج: استفاده از JavaScript به‌عنوان تنها دفاع

Frame-busting Script می‌تواند لایه تکمیلی باشد ولی Browser Headerها قابل اتکاتر هستند.

اشتباه رایج: استفاده از Policy بیش از حد باز

مثلاً اگر یک Site فقط باید توسط یک Partner Frame شود اما Policy اجازه تعداد زیادی Domain را می‌دهد، Attack Surface غیرضروری افزایش پیدا می‌کند.

Allowlist باید حداقلی باشد.

اشتباه رایج: فراموش کردن Subdomainها

Subdomain نیز بخشی از Trust Model است.

اگر Wildcard وسیع استفاده شود، Compromise شدن یک Subdomain می‌تواند Policy را بی‌اثرتر کند.

مثلاً Allow کردن تمام Subdomainها باید تصمیمی آگاهانه باشد.

اشتباه رایج: اعمال Header فقط روی Homepage

Attack معمولاً صفحه دارای Action را هدف می‌گیرد.

ممکن است Homepage کاملاً Protected باشد اما:

/account/settings

بدون Header مناسب Response شود.

Policy باید روی Routeهای واقعی بررسی شود.

چگونه Clickjacking را به‌صورت دفاعی تست کنیم؟

هدف تست این است که بررسی شود Browser اجازه Framing صفحه حساس را می‌دهد یا نه.

اول Headerهای Response را بررسی کنید.

به دنبال موارد زیر باشید:

Content-Security-Policy

و:

X-Frame-Options

اگر CSP وجود دارد، بررسی کنید frame-ancestors صریحاً تعریف شده باشد.

وجود CSP بدون frame-ancestors به‌تنهایی اثبات Anti-clickjacking Protection نیست.

بررسی DevTools

در Browser Developer Tools:

Network را باز کنید.

Document اصلی را انتخاب کنید.

Response Headers را بررسی کنید.

بررسی با curl

برای بررسی Header Response می‌توان از ابزارهای استاندارد HTTP Client استفاده کرد و فقط Headerها را مشاهده کرد.

هدف Test باید Verification دفاعی باشد.

بررسی در Environment کنترل‌شده

اگر Permission دارید، می‌توانید در یک Test Page متعلق به خودتان تلاش کنید Page موردنظر را داخل iframe Load کنید.

Browser باید براساس Policy موردنظر Frame را Block کند.

این تست روی Site دیگر بدون مجوز نباید انجام شود.

نشانه‌های Vulnerability در Review

موارد زیر نیازمند بررسی بیشتر هستند:

صفحات Sensitive بدون frame-ancestors

نبود X-Frame-Options در Environmentهای Legacy موردنیاز

Cookieهای Session با SameSite نامناسب بدون دلیل

اعتماد به Meta Tag

اعتماد صرف به JavaScript Frame Busting

صفحات دارای عملیات Critical که Frameable هستند

Allowlist بسیار وسیع

Wildcard Domain غیرضروری

تفاوت Policy میان CDN و Origin

Headerهای حذف‌شده توسط Proxy یا Cache

OWASP هشدار می‌دهد Proxyها می‌توانند Security Headerهایی مانند X-Frame-Options را اضافه یا حذف کنند؛ بنابراین Response نهایی باید بررسی شود.

Reverse Proxy و CDN چه نقشی دارند؟

در بسیاری از معماری‌ها Header نهایی مستقیماً از Application به Browser نمی‌رسد.

مسیر ممکن است:

Application

→ Nginx

→ Reverse Proxy

→ CDN

→ WAF

→ Browser

باشد.

هر Layer ممکن است Header را:

اضافه کند،

Override کند،

حذف کند.

به همین دلیل Source Code به‌تنهایی کافی نیست.

Browser باید در Response Production Header صحیح را ببیند.

تنظیم Anti-clickjacking در سطح Web Server

بعضی تیم‌ها Policy را در Application Code تنظیم می‌کنند.

بعضی در Web Server.

برای Policy عمومی Site، Server یا Reverse Proxy می‌تواند مکان مناسبی باشد.

مثلاً هدف مفهومی می‌تواند این باشد:

CSP:

frame-ancestors 'none'

و برای Compatibility:

X-Frame-Options: DENY

اگر Site نیازمند Same-origin iframe است:

frame-ancestors 'self'

و:

X-Frame-Options: SAMEORIGIN

اما Configuration دقیق باید با Architecture، CDN و Embed Requirementهای واقعی هماهنگ شود.

Defense in Depth برای Clickjacking

مدل دفاعی مناسب معمولاً یک Control واحد نیست.

لایه اول: محدود کردن Framing

CSP frame-ancestors

لایه دوم: Compatibility

X-Frame-Options در صورت نیاز

SameSite مناسب

لایه چهارم: طراحی عملیات حساس

Confirmation

Re-authentication

MFA

لایه پنجم: Monitoring و Security Review

بررسی Headerهای Production

لایه ششم: Frame Busting در Legacy Context خاص

در صورت نیاز واقعی

این رویکرد باعث می‌شود شکست یک لایه الزاماً کل Protection را از بین نبرد.

Content Security Policy فقط برای Clickjacking نیست

CSP مجموعه‌ای گسترده‌تر از Policyهای Browser Security است.

برای مثال می‌تواند Sourceهای مجاز Script، Style، Image و موارد دیگر را نیز کنترل کند.

اما مهم است Directiveها را با هم اشتباه نکنیم.

برای Clickjacking:

frame-ancestors

Directive اصلی است.

OWASP نیز CSP را یک لایه مهم Defense in Depth برای Web Applicationها می‌داند، اما تأکید می‌کند CSP جای Secure Development Practiceها را نمی‌گیرد.

آیا Clickjacking هنوز در Browserهای مدرن اهمیت دارد؟

بله، هرچند ابزارهای دفاعی Browser بسیار بهتر از گذشته شده‌اند.

وجود CSP و X-Frame-Options باعث شده Prevention نسبتاً ساده باشد.

اما مشکل زمانی باقی می‌ماند که:

Header تنظیم نشده،

Policy اشتباه است،

Route خاصی فراموش شده،

Integration نیازمند iframe بوده و Policy بیش از حد باز شده،

Cookie Configuration مناسب نیست،

یا تیم فقط به UI Layer اعتماد کرده است.

بنابراین Clickjacking از آن دسته ضعف‌هایی است که Prevention آن آسان‌تر از بسیاری از Vulnerabilityها است، اما یک Configuration ناقص می‌تواند Risk را دوباره ایجاد کند.

آیا هر سایتی که iframe می‌شود آسیب‌پذیر است؟

خیر.

این جمله بیش از حد ساده‌سازی‌شده است.

Frameable بودن یک Property است.

برای تعیین Risk باید بررسی کنیم:

چه چیزی Frame می‌شود؟

User Login است یا نه؟

چه Controlهایی روی صفحه وجود دارند؟

چه Actionهایی قابل انجام‌اند؟

Action چه Impactی دارد؟

آیا Confirmation اضافی وجود دارد؟

SameSite Cookie چگونه تنظیم شده؟

بنابراین Vulnerability Assessment باید Context-aware باشد.

Clickjacking و صفحات عمومی

یک Article عمومی که تنها Text نمایش می‌دهد احتمالاً Impact پایینی دارد.

اما همان Site ممکن است Route دیگری داشته باشد که:

Account Setting

Subscription

Admin Action

را انجام دهد.

به همین دلیل Security Headerها بهتر است با یک Policy منظم و مرکزی مدیریت شوند، نه اینکه Developer هر Page را جداگانه به خاطر بسپارد.

نقش Secure by Design

بهترین زمان تصمیم‌گیری درباره Framing قبل از Production است.

در Security Requirement باید سؤال شود:

آیا این Page باید Embeddable باشد؟

اگر بله، چه Originهایی؟

اگر نه، چرا Framing به‌طور کامل Block نشود؟

Session Cookie چه SameSite Policy دارد؟

آیا Action حساس Step-up Authentication نیاز دارد؟

به این ترتیب Anti-clickjacking Protection بخشی از Architecture می‌شود، نه Patch بعدی.

نقش Threat Modeling

در Threat Modeling می‌توان UI Boundaryها را نیز بررسی کرد.

برای هر Feature حساس بپرسید:

آیا Page قابل Embed است؟

اگر User از قبل Login باشد چه؟

اگر Action با یک Click اجرا شود چه؟

آیا User Context قبل از Operation واضح است؟

آیا Origin دیگری نیازمند iframe است؟

این سؤالات Design Weakness را قبل از تبدیل شدن به Incident مشخص می‌کنند.

نقش Penetration Testing

در تست امنیت مجاز، Clickjacking Testing می‌تواند شامل:

بررسی Security Headers

بررسی Routeهای حساس

بررسی Framing Policy

بررسی Session Behavior در iframe

بررسی SameSite

تحلیل Impact Actionها

باشد.

مهم‌ترین نکته این است که نتیجه تست فقط عبارت:

«X-Frame-Options وجود ندارد»

نباشد.

ممکن است Application با CSP frame-ancestors به‌درستی محافظت شده باشد و نبود X-Frame-Options به‌تنهایی Vulnerability نباشد.

برعکس، وجود X-Frame-Options روی یک Route و نبود Protection روی Route حساس دیگر نیز کافی نیست. چک‌لیست جلوگیری از Clickjacking

چک‌لیست جلوگیری از Clickjacking

Framing Policy

  • مشخص کنید آیا سایت اصلاً نیاز به iframe دارد.
  • اگر نیاز ندارد، frame-ancestors 'none' را بررسی کنید.
  • اگر فقط Same-origin نیاز است، 'self' را بررسی کنید.
  • برای Integrationها Allowlist حداقلی تعریف کنید.
  • Wildcardهای غیرضروری را حذف کنید.

X-Frame-Options

  • در صورت نیاز Compatibility از DENY یا SAMEORIGIN استفاده کنید.
  • از ALLOW-FROM استفاده نکنید.
  • Header را از طریق HTTP Response بفرستید.
  • X-Frame-Options را داخل Meta Tag قرار ندهید.

CSP

  • frame-ancestors را صریحاً تعریف کنید.
  • تصور نکنید default-src جای آن را می‌گیرد.
  • آن را داخل meta قرار ندهید.
  • Response Production را بررسی کنید.
  • Allowlist را محدود نگه دارید.

Session

  • SameSite Cookieها را بررسی کنید.
  • Session Cookie را با Secure و HttpOnly متناسب با نیاز Application مدیریت کنید.
  • Cross-site Requirement واقعی را مستند کنید.
  • از SameSite=None بدون نیاز واقعی استفاده نکنید.

عملیات حساس

  • عملیات مهم را با یک Click ساده نهایی نکنید.
  • Confirmation واضح ایجاد کنید.
  • برای Actionهای بسیار حساس Re-authentication را بررسی کنید.
  • MFA یا Step-up Authentication را در Context مناسب استفاده کنید.

WordPress

  • Header واقعی Response را بررسی کنید.
  • Pluginهای Security Header را کورکورانه Trust نکنید.
  • CDN و Cache را بررسی کنید.
  • REST/Custom Pages و Endpointهای HTML را فراموش نکنید.
  • WooCommerce Integrationهایی که iframe نیاز دارند قبل از تغییر Policy تست شوند.

Monitoring و QA

  • Headerها را در CI/CD یا Security Test بررسی کنید.
  • Routeهای جدید را برای Framing Requirement Review کنید.
  • بعد از تغییر CDN یا Web Server دوباره تست کنید.
  • Security Headerها را فقط یک بار در زمان Launch بررسی نکنید.

اشتباهات رایج در جلوگیری از Clickjacking

۱. فقط X-Frame-Options و بدون CSP

X-Frame-Options هنوز مفید است، اما frame-ancestors راهکار مدرن‌تر و انعطاف‌پذیرتر است.

۲. فقط CSP بدون frame-ancestors

داشتن Content-Security-Policy به‌تنهایی کافی نیست.

باید Directive مربوط به Framing وجود داشته باشد.

۳. استفاده از HTML Meta Tag

Anti-framing Headerهای موردبحث باید در HTTP Response تنظیم شوند.

۴. تکیه بر CSRF Token

CSRF Token و Clickjacking دو Risk متفاوت را هدف می‌گیرند.

۵. تکیه بر CORS

CORS نمی‌گوید چه کسی اجازه Frame کردن Document را دارد.

۶. تکیه کامل بر SameSite

SameSite مکمل است.

۷. Frame-busting JavaScript به‌عنوان تنها دفاع

روش‌های Browser-enforced قابل اعتمادتر هستند.

۸. Allowlist بیش از حد گسترده

هر Origin مجاز بخشی از Trust Boundary شما است.

۹. نادیده گرفتن صفحات Account و Admin

Protection فقط Homepage کافی نیست.

۱۰. بررسی نکردن Response نهایی

ممکن است Source Code درست باشد ولی CDN Header را تغییر دهد.

چگونه Headerهای Clickjacking را در WordPress مدیریت کنیم؟

WordPress Core ابزارهایی برای ارسال Headerهای Framing دارد و Function رسمی send_frame_options_header() در نسخه فعلی هم X-Frame-Options SAMEORIGIN و هم CSP frame-ancestors 'self' را ارسال می‌کند.

همچنین WordPress Hookهایی مانند wp_headers اجازه فیلتر کردن HTTP Headerها را پیش از ارسال می‌دهند.

اما اگر Page توسط Full-page Cache یا CDN قبل از رسیدن به WordPress Serve شود، Header نهایی ممکن است در Layer دیگری مدیریت شود.

بنابراین برای رخنه‌کاو یا هر سایت WordPress دیگر، معیار نهایی Browser Response است، نه فقط تنظیم PHP.

آیا Security Plugin برای جلوگیری از Clickjacking کافی است؟

ممکن است Plugin مناسب Headerهای لازم را اضافه کند، اما «نصب بودن Plugin» اثبات امنیت نیست.

باید بررسی شود:

Header واقعاً ارسال می‌شود؟

روی تمام Pageهای حساس ارسال می‌شود؟

CDN آن را حذف نکرده؟

Policy با WooCommerce یا Widgetها Conflict ندارد؟

اگر Plugin غیرفعال شود چه؟

Security Control مهم بهتر است بخشی از Configuration مستند زیرساخت باشد.

چه زمانی نباید DENY استفاده کنیم؟

اگر Product شما باید توسط Application دیگری Frame شود، DENY Integration را می‌شکند.

در چنین حالتی باید Requirement دقیق باشد.

مثلاً فقط:

Dashboard شرکت Parent

Portal Partner

اجازه Framing داشته باشند.

CSP frame-ancestors برای چنین سناریویی مناسب‌تر است.

آیا Clickjacking می‌تواند روی Mobile Web رخ دهد؟

اصل Attack وابسته به Rendering Browser و Framing است، نه Desktop بودن دستگاه.

بنابراین Web Application موبایلی نیز باید Policy مناسب داشته باشد.

ممکن است Layout، Touch Target و UX متفاوت باشند، اما Anti-framing Requirement همچنان معتبر است.

آیا Native Mobile App در برابر Clickjacking وب آسیب‌پذیر است؟

Native Application Context متفاوت است.

اما اگر App از WebView استفاده کند یا صفحات Web حساس را Embed کند، Threat Model مربوط به UI Redressing و Web Content همچنان باید بررسی شود.

این موضوع لزوماً همان Clickjacking کلاسیک Browser نیست، اما اعتماد به Embedded Web Content باید مشخص باشد.

Clickjacking و صفحات Login

گاهی User Login Page داخل iframe قرار می‌گیرد.

حتی اگر Action مستقیم خطرناک نباشد، UI Redressing می‌تواند User را گیج کند.

در بسیاری از Applicationها دلیلی وجود ندارد که Login Page توسط Origin خارجی Frame شود.

بنابراین Login، Account و Admin Pageها معمولاً Candidateهای خوبی برای Anti-framing سخت‌گیرانه هستند.

Clickjacking و مجوزهای حساس

عملیاتی که اثر امنیتی قابل توجه دارند بهتر است فقط به یک Click متکی نباشند.

مثلاً تغییر:

Email اصلی

MFA Setting

Security Key

Payment Destination

Permission

Admin Role

می‌تواند به Confirmation و Re-authentication نیاز داشته باشد.

این تصمیم علاوه بر Clickjacking در برابر Session Abuse و Mistakeهای انسانی نیز مفید است.

آیا پنهان کردن Button حساس کافی است؟

خیر.

CSS و UI Access Control امنیت نیستند.

اگر User از نظر Server مجاز به Action نیست، Authorization باید سمت Server انجام شود.

Clickjacking یادآوری خوبی است که چیزی که User «می‌بیند» نباید مبنای Security Decision باشد.

Clickjacking و Accessibility

Controlهای ضد Clickjacking نباید باعث شوند Application Accessibility را نادیده بگیرد.

برای مثال Confirmationهای اضافه باید برای Keyboard، Screen Reader و Userهای دارای محدودیت دسترسی قابل استفاده باشند.

Secure UX باید همزمان:

قابل فهم،

قابل دسترس،

و امن

باشد.

امنیت واقعی در Clickjacking از کجا شروع می‌شود؟

از یک سؤال ساده:

آیا Page من باید توسط سایت دیگری داخل Frame نمایش داده شود؟

اگر پاسخ «نه» است، Browser باید این موضوع را بداند.

اگر پاسخ «بله» است:

چه Siteهایی؟

چرا؟

کدام Routeها؟

با چه Session Policy؟

و با چه Impactی؟

این تصمیم ساده بخش بزرگی از Attack Surface مربوط به Clickjacking را مشخص می‌کند.

سوالات متداول درباره Clickjacking

Clickjacking چیست؟

Clickjacking حمله‌ای از نوع UI Redressing است که در آن مهاجم User را فریب می‌دهد تا روی یک عنصر واقعی از Site دیگر کلیک کند، در حالی که تصور می‌کند روی عنصر متفاوتی تعامل دارد.

کلیک‌جکینگ چگونه انجام می‌شود؟

در مدل رایج، Site هدف داخل iframe قرار می‌گیرد و Layout آن با عناصر صفحه مهاجم هم‌تراز می‌شود. اگر User در سایت هدف Login باشد، Click می‌تواند در Session واقعی او پردازش شود.

بهترین راه جلوگیری از Clickjacking چیست؟

مهم‌ترین روش محدود کردن Framing با CSP frame-ancestors است. X-Frame-Options و SameSite Cookie نیز می‌توانند لایه‌های دفاعی مکمل باشند.

CSP frame-ancestors چیست؟

Directiveی از Content Security Policy است که مشخص می‌کند چه Parent Originهایی مجاز هستند Page را داخل frame، iframe، object یا embed قرار دهند.

frame-ancestors 'none' چه می‌کند؟

اجازه نمی‌دهد هیچ Originی Page را Frame کند. این Policy برای Pageهایی مناسب است که هیچ نیاز قانونی به Embedding ندارند.

frame-ancestors 'self' چه می‌کند؟

فقط Same-origin Framing را اجازه می‌دهد.

X-Frame-Options چیست؟

HTTP Response Header قدیمی‌تر برای کنترل Framing است. مقادیر اصلی آن DENY و SAMEORIGIN هستند.

DENY و SAMEORIGIN چه تفاوتی دارند؟

DENY تمام Framing را Block می‌کند. SAMEORIGIN فقط Frame شدن توسط همان Origin را مجاز می‌کند.

آیا ALLOW-FROM توصیه می‌شود؟

خیر. این Directive منسوخ شده و در Browserهای مدرن قابل اتکا نیست. برای Allowlist از CSP frame-ancestors استفاده شود.

آیا X-Frame-Options داخل meta کار می‌کند؟

خیر. باید به شکل HTTP Response Header ارسال شود.

آیا CSP frame-ancestors داخل meta کار می‌کند؟

خیر. استاندارد CSP مشخص می‌کند frame-ancestors در Policy تعریف‌شده از طریق meta نادیده گرفته می‌شود.

آیا SameSite جلوی Clickjacking را می‌گیرد؟

SameSite می‌تواند بعضی Scenarioها را کاهش دهد، زیرا Session Cookie ممکن است در Cross-site iframe ارسال نشود؛ اما یک لایه دفاعی مکمل است و جای frame-ancestors را نمی‌گیرد. تفاوت Clickjacking با CSRF و XSS چیست؟

تفاوت Clickjacking و CSRF چیست؟

Clickjacking بر فریب User و Manipulation رابط کاربری تکیه دارد، در حالی که CSRF روی جعل Request از Context User تمرکز می‌کند.

آیا CSRF Token Clickjacking را متوقف می‌کند؟

نه همیشه. User ممکن است مستقیماً با فرم واقعی و Token معتبر موجود داخل iframe تعامل کند.

تفاوت Clickjacking و XSS چیست؟

XSS شامل اجرای Script غیرمجاز در Origin هدف است. Clickjacking می‌تواند بدون Inject کردن Script در سایت هدف انجام شود و تمرکز آن بر رابط کاربری است.

آیا CORS جلوی Clickjacking را می‌گیرد؟

خیر. CORS و Framing Policy دو مکانیزم متفاوت هستند.

Frame Busting چیست؟

روش JavaScriptی برای تشخیص Load شدن Page در Frame و تلاش برای خروج از آن است. امروزه Headerهای استاندارد Browser-enforced راهکار اصلی هستند.

آیا iframe sandbox ضد Clickjacking است؟

sandbox برای محدود کردن Capabilityهای Contentی است که خودتان داخل iframe Load می‌کنید. برای جلوگیری از Frame شدن صفحه خودتان باید Framing Policy مناسب مانند frame-ancestors داشته باشید.

آیا WordPress در برابر Clickjacking کنترل داخلی دارد؟

WordPress تابع send_frame_options_header() را دارد که در نسخه فعلی X-Frame-Options SAMEORIGIN و CSP frame-ancestors 'self' ارسال می‌کند. با این حال Response واقعی Pageهای Production باید بررسی شود، زیرا Cache، CDN و Custom Code می‌توانند Headerها را تغییر دهند.

آیا WooCommerce هم به بررسی Clickjacking نیاز دارد؟

بله، به‌ویژه Pageهای Account، Checkout، Payment Integration و Extensionهای سفارشی. اگر Gateway برای عملکرد قانونی iframe نیاز داشته باشد، Framing Policy باید با همان Integration هماهنگ شود.

آیا Clickjacking فقط برای صفحات Admin خطرناک است؟

خیر. هر Page دارای Action ارزشمند می‌تواند Target باشد؛ هرچند Admin و Account Pages معمولاً Impact بیشتری دارند.

آیا HTTPS از Clickjacking جلوگیری می‌کند؟

خیر. HTTPS ارتباط را رمزگذاری می‌کند، اما مشخص نمی‌کند چه Siteهایی می‌توانند Page را داخل iframe قرار دهند.

آیا WAF جلوی Clickjacking را می‌گیرد؟

WAF ممکن است لایه‌های امنیتی دیگری ایجاد کند، اما Anti-framing باید از طریق Browser Policy مناسب پیاده‌سازی شود.

جمع‌بندی

Clickjacking یکی از نمونه‌های مهم این واقعیت است که امنیت وب فقط درباره جلوگیری از اجرای Code مخرب یا سرقت Password نیست.

گاهی مهاجم نیازی ندارد Authentication را دور بزند.

کافی است User احراز هویت‌شده را وادار کند روی کنترل واقعی Application کلیک کند.

در حمله Clickjacking، Page هدف معمولاً داخل iframe سایت دیگری قرار می‌گیرد و رابط ظاهری به شکلی طراحی می‌شود که User هدف واقعی Click را نبیند.

به همین دلیل Clickjacking در خانواده UI Redressing قرار دارد.

مهم‌ترین دفاع این است که Application به Browser بگوید چه Originهایی اجازه Frame کردن Page را دارند.

برای Applicationهای مدرن، CSP frame-ancestors کنترل اصلی و انعطاف‌پذیر است.

اگر Site نباید Frame شود:

frame-ancestors 'none'

و اگر فقط Same-origin Framing لازم است:

frame-ancestors 'self'

می‌تواند مبنای Policy باشد.

X-Frame-Options: DENY یا SAMEORIGIN نیز همچنان می‌تواند برای Compatibility و Defense in Depth کاربرد داشته باشد، اما قابلیت منسوخ ALLOW-FROM نباید مبنای طراحی مدرن قرار گیرد.

SameSite Cookie نیز لایه تکمیلی مهمی است.

اگر Session Cookie در Cross-site iframe ارسال نشود، بسیاری از Clickjacking Scenarioهای وابسته به Login Context سخت‌تر می‌شوند.

با این حال SameSite جای Anti-framing Policy را نمی‌گیرد.

همین موضوع درباره CSRF Token، CORS، WAF و Frame-busting JavaScript نیز صدق می‌کند.

هیچ‌کدام جای frame-ancestors را نمی‌گیرند.

در عملیات بسیار حساس نیز Secure by Design اهمیت دارد.

Actionهایی مانند تغییر Credential، Security Setting، Payment Setting یا Permission بهتر است فقط با یک Click خام نهایی نشوند.

Confirmation واضح، Re-authentication و MFA می‌توانند Impact سوءاستفاده را کاهش دهند.

برای سایت‌های WordPress و WooCommerce نیز مهم‌ترین کار بررسی Response واقعی است.

WordPress ابزار داخلی برای ارسال Headerهای Framing دارد، اما CDN، Reverse Proxy، Cache، Plugin و Custom Architecture می‌توانند Policy نهایی را تغییر دهند. بنابراین Browser باید معیار نهایی بررسی باشد.

در نهایت Clickjacking را می‌توان با یک سؤال ساده مدیریت کرد:

«چه کسی واقعاً باید اجازه داشته باشد این صفحه را داخل سایت خودش نمایش دهد؟»

اگر پاسخ هیچ‌کس است، Framing را Block کنید.

اگر پاسخ چند Origin مشخص است، همان‌ها را با Policy حداقلی مجاز کنید.

وقتی Trust Boundary مربوط به Framing به‌درستی تعریف شود، بخش بزرگی از Attack Surface کلیک‌جکینگ قبل از رسیدن Click کاربر حذف خواهد شد.

مطالب مرتبط