ابزار بررسی iframe
بررسیگر آنلاین رایگان iframe: هر نشانی صفحه وب را وارد کنید تا هدرهای X-Frame-Options و Content-Security-Policy frame-ancestors آن بررسی شود، مشخص کنید آیا صفحه قابلیت قرارگیری در iframe را دارد یا خیر، و نتیجه را با پیشنمایش زنده تأیید نمایید. تاریخچه بررسیها فقط مختص همین نشست مرورگر ذخیره میشود.
تاریخچه (این نشست)
تنها در این تب ذخیره میشود (sessionStorage)؛ هنگام بستن تب پاک میگردد. هیچ دادهای به سرور ارسال نمیشود.
نحوه عملکرد بررسی
- نشانی هدف را وارد کرده و روی «بررسی» کلیک کنید. سرور صفحه را دقیقاً مانند یک درخواست واقعی iframe (با Sec-Fetch-Dest: iframe) فراخوانی کرده و هدرهای پاسخ آن را میخواند.
- نتیجه نهایی بر اساس X-Frame-Options (مقادیر DENY/SAMEORIGIN مانع فریمبندی میشوند) و Content-Security-Policy frame-ancestors (فقط * یا یک scheme خاص اجازه اتصال دلخواه والدین شخص ثالث را میدهد) تعیین میگردد.
- همان نشانی در iframe پیشنمایش زنده بارگذاری میشود تا بتوانید واکنش واقعی مرورگر را تأیید کنید، از جمله مواردی که جاوااسکریپت باعث خروج از iframe میشود و هدرها قادر به نمایش آن نیستند.
چه عواملی بر قابلیت تعبیه یک صفحه تأثیر میگذارند؟
اینکه آیا یک صفحه وب میتواند درون <iframe> در سایت دیگری نمایش داده شود، توسط مرورگر و بر پایه هدرهای پاسخ ارسالی از سمت خودِ صفحه تصمیمگیری میشود. این ابزار همان بررسی را در سمت سرور انجام میدهد و بلافاصله نتیجه را به شما اعلام میکند.
X-Frame-Options یک هدر استاندارد قدیمی است: DENY تمام انواع نمایش در iframe را منع میکند، SAMEORIGIN فقط به صفحات هممنبع اجازه میدهد، و ALLOW-FROM از مرورگرهای مدرن حذف شده است. در غیاب این هدر، قوانین قدیمی مانع نمایش iframe نمیشوند.
CSP frame-ancestors جایگزین مدرن آن است. این ویژگی فهرست originهایی است که اجازه جاگذاری صفحه را دارند — مانند `frame-ancestors 'self' https://example.com`. مقدار * (یا صرفاً یک طرح مثل https:) به هر والد HTTPS اجازه میدهد؛ مقادیر محدودتر، جاگذاری توسط شخص ثالث را مسدود میکنند.
هدرها تنها بخش داستان نیستند: اسکریپتهای صفحه ممکن است کدهای متوقفکننده iframe اجرا کنند (مقایسه top !== self و الزام به ناوبری سطح بالا)، و صفحات ورود یا endpointهای محدود به منطقه جغرافیایی ممکن است برای درخواستهای دیتاسنتر رفتار متفاوتی داشته باشند. به همین دلیل هر نتیجه همراه با پیشنمایش زنده ارائه میشود.
راهنمای سریع: تنظیم هدرهای پاسخ
اگر مالک وبسایت هستید، کنترل نمایش در iframe را مستقیماً از طریق هدرهای پاسخ مدیریت کنید.
مسدود کردن جاگذاری از هر صفحهای
X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none'
مرورگرها از رندر شدن صفحه در هیچ iframeای خودداری میکنند — این سختگیرانهترین روش محافظت در برابر کلیکجکینگ (Clickjacking) است.
فقط اجازه جاگذاری از هممنبع
X-Frame-Options: SAMEORIGIN
Content-Security-Policy: frame-ancestors 'self'
فقط صفحاتی که دارای طرح (scheme)، میزبان (host) و پورت یکسان هستند مجاز به نمایش آن در iframe میباشند؛ سایتهای شخص ثالث مسدود خواهند شد.
فقط اجازه جاگذاری از originهای خاص
Content-Security-Policy: frame-ancestors 'self' https://trusted.example.com
originهای مورد اعتماد را در frame-ancestors فهرست کنید؛ منابعی که در لیست نیستند، مسدود میشوند.
اجازه جاگذاری از هر صفحهای
هدر X-Frame-Options را ست نکنید
Content-Security-Policy: frame-ancestors *
هر سایتی میتواند این صفحه را در یک iframe نمایش دهد. پیش از فعالسازی، تعادل امنیتی آن را ارزیابی کنید.
نکته: هدر CSP frame-ancestors جایگزین مدرنتر برای X-Frame-Options است. هنگامی که هر دو بهکار رفته باشند، اولویت با CSP است — استفاده از frame-ancestors توصیه میشود.
سرور چگونه تشخیص میدهد درخواست از داخل یک iframe ارسال شده است؟
از حدود سال ۲۰۲۰، مرورگرهای مبتنی بر کرومیم و فایرفاکس بهطور خودکار یک مجموعه از هدرهای درخواست Fetch Metadata را به هر ناوبری و درخواست زیرمنبع اضافه میکنند. مفیدترین آن برای بررسیهای iframe، Sec-Fetch-Dest است — به سرور میگوید چه نوع محیطی منبع را درخواست کرده، بدون نیاز به همکاری صفحه درخواستدهنده.
- Sec-Fetch-Dest: document — ناوبری سطح بالا (اصلی)، نه درون هیچ چارچوبی.
- Sec-Fetch-Dest: iframe — درخواست درون المان <iframe> بارگذاری میشود.
- Sec-Fetch-Dest: frame — بارگذاری درون تگ قدیمی <frame> (frameset).
- Sec-Fetch-Dest: embed / object — بارگذاری درون المان <embed> یا <object>.
این بررسیگر نمونه درخواست (Probe) خود را با هدر `Sec-Fetch-Dest: iframe` ارسال میکند که دقیقاً منطبق بر دادههایی است که یک مرورگر واقعی هنگام قرار دادن صفحه در قاب ارسال میکند؛ بنابراین نتیجه نشان میدهد سرور هدف در مواجهه با درخواستهای iframe معتبر چگونه عمل میکند، نه صرفاً یک درخواست fetch معمولی.
`Sec-Fetch-Dest` یک سیگنال مفید اما مرز امنیتی محسوب نمیشود؛ زیرا تنها توسط مرورگرهای مدرن ارسال میشود و مشتریان غیرمرورگری نظیر curl، رباتها، برخی وبویوها و مرورگرهای قدیمی ممکن است آن را کاملاً حذف کرده یا یک مقدار دلخواه ارسال کنند. سرور میتواند بر پایه آن لاگ ثبت کند یا قانون rate-limiting اعمال نماید، اما هرگز نباید تنها به آن تکیه کند تا تشخیص دهد آیا قابسازی ایمن است یا خیر؛ این تصمیم همچنان بر عهده هدرهای `X-Frame-Options` و `CSP frame-ancestors` است که مرورگرها بدون توجه به هدرهای درخواست، آنها را اعمال میکنند.
در سمت کلاینت، یک صفحه میتواند حتی بدون هیچ هدری تشخیص دهد که درون یک قاب اجرا میشود؛ مثلاً با مقایسه `window.top !== window.self` (یا خواندن `window.frameElement` برای قابهای همآدرس مبدأ)، سپس واکنش نشان دهد — نمایش هشدار یا اجرای ریدایرکت سطح بالا. این همان تکنیک frame-busting است که پیشتر اشاره شد و صرفنظر از محتوای هدرهای درخواست کارآمد است.
نمونههایی از تنظیمات سرور: مسدودسازی تعبیه iframe
قطعهکدهای زیر نحوه پیکربندی هر سرور یا فریمورک برای مسدودسازی کامل نمایش در iframe (X-Frame-Options: DENY + CSP frame-ancestors 'none') را نشان میدهند — این گزینه سختگیرانهترین حالت از میان راهکارهای راهنمای سریع بالاست.
server {
location / {
add_header X-Frame-Options "DENY" always;
add_header Content-Security-Policy "frame-ancestors 'none'" always;
}
}
<IfModule mod_headers.c>
Header always set X-Frame-Options "DENY"
Header always set Content-Security-Policy "frame-ancestors 'none'"
</IfModule>
app.use((req, res, next) => {
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "frame-ancestors 'none'");
next();
});
// next.config.js
module.exports = {
async headers() {
return [
{
source: '/:path*',
headers: [
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'Content-Security-Policy', value: "frame-ancestors 'none'" },
],
},
];
},
};
class SetFrameOptions
{
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('X-Frame-Options', 'DENY');
$response->headers->set('Content-Security-Policy', "frame-ancestors 'none'");
return $response;
}
}
export default {
async fetch(request) {
const response = await fetch(request);
const headers = new Headers(response.headers);
headers.set('X-Frame-Options', 'DENY');
headers.set('Content-Security-Policy', "frame-ancestors 'none'");
return new Response(response.body, { status: response.status, headers });
},
};
فقط میخواهید سایت خودتان یا لیست کوچکی از دامنههای مجاز را برای نمایش صفحه اجازه دهید و بقیه را مسدود کنید؟ مقدار DENY را به SAMEORIGIN و 'none' را به 'self' یا لیستی صریح از originها تغییر دهید — مابقی تنظیمات بدون تغییر باقی میمانند.
نکات مهم درباره پلتفرمهای خاص
فراتر از قوانین عمومی هدرها، برخی پلتفرمهای شناختهشده قواعد یا رفتارهای خاص خود را دارند؛ دانستن این موارد پیش از آنکه صرفاً بر اساس هدرها فرض کنید محتوایی «مسدود» یا «قابل تعبیه» است، ضروری است.
| پلتفرم / سناریو | وضعیت | دلیل |
|---|---|---|
| صفحه پخش یوتیوب (youtube.com/watch) | مسدود شده | به جای آن از آدرس پلیر رسمی youtube.com/embed/{id} استفاده کنید — صفحه پخش معمولی یک سیاست قابسازی محدودکننده ارسال میکند. |
| صفحه مکان در گوگل مپس | مسدود شده | تنها آدرس iframe ارائهشده توسط Maps Embed API (google.com/maps/embed) برای قرارگیری در قاب طراحی شده است. |
| صفحات ورود OAuth گوگل یا مایکروسافت | مسدود شده | عمدتاً از سال ۲۰۱۵ مسدود شده تا از فیشینگ اطلاعات ورود در داخل iframe جلوگیری شود؛ فرآیند ورود باید در یک پنجره سطح بالا یا پاپآپ اجرا گردد. |
| صفحات تسویه حساب پرداخت (Stripe Checkout، PayPal، بیشتر درگاههای بانکی) | مسدود شده | قابسازی فرم پرداخت یک کانال کلاسیک حمله Clickjacking محسوب میشود، بنابراین پردازشگرهای مالی آن را مستقیماً رد میکنند. |
| صفحه مخزن یا فایل گیتهاب | مسدود شده | تنظیم سایتگسترده `frame-ancestors 'none'` دارد؛ به جای iframe از APIهای REST یا GraphQL یا اسکرینشات استفاده کنید. |
| صفحات «انتشار در وب» Notion یا Google Docs | قابل تعبیه | صراحتاً برای تعبیه شدن طراحی شدهاند و محصول کد آمادهای برای این منظور ارائه میدهد. |
| مقالات ویکیپدیا | قابل تعبیه | بهطور پیشفرض هدرهای محدودکننده `X-Frame-Options` یا `CSP` ندارند، اما پیش از تعبیه گسترده، شرایط حق تکثیر و انتساب منبع را بررسی کنید. |
موارد کاربرد رایج
- پیش از نوشتن کد یکپارچهسازی، مشخص کنید که آیا ویجت، داشبورد یا سند شخص ثالث قابل تعبیه در محصول شماست یا خیر.
- اطمینان حاصل کنید که سایت شما دقیقاً همین سیاست `X-Frame-Options` یا `CSP frame-ancestors` مد نظر را ارسال میکند.
- عیبیابی مکانیزمهای محافظت در برابر کلیکجکینگ: بررسی کنید که چرا یک صفحه درون قاب (iframe) به جای محتوا، تنها فضای خالی (about:blank) یا پیامی مبنی بر رد درخواست را نشان میدهد.
- بررسی گروهی آدرسهای URL انتخابی در فرآیند تجمیع محتوا یا یکپارچهسازی پورتال و امکان مرور مجدد نتایج از طریق تاریخچه نشست.
- تهیه مستندات مربوط به سیاست قاببندی (Framing Policy) وابستگیهای خارجی جهت آمادهسازی برای ارزیابیهای امنیتی یا تست نفوذ.