پیشنمایش امن برای HTMLی که هوش مصنوعی میسازه
خلاصهٔ کاملتر
نویسندهٔ این مقاله که مهندس امنیته، تعریف میکنه یه بار HTMLی که مدل براش ساخته بود رو بدون خوندن تو یه iframe روی دامنهٔ خودش رندر کرده و بعد فهمیده چه ریسکی کرده. حرف اصلیش اینه که هر محصولی که مدل توش UI میسازه یه پیشنمایش لازم داره، و اون پیشنمایش تنها جاییه که کد غیرقابلاعتماد عمداً تو اپ اجرا میشه. چون پرامپت میتونه از کاربر یا یه سند خارجی بیاد، خروجی مدل رو باید مثل کد یه غریبه دید.
نسخهٔ اولی که همه مینویسن خیلی سادهست و به نظر محتاطانه میاد، چون از srcdoc (یعنی دادن HTML مستقیم به iframe بهجای URL) استفاده میکنه:
const html = modelOutput; // whatever the model returned
document.querySelector('#preview').srcdoc = html;مشکل اینه که iframe با srcdoc و بدون ویژگی sandbox روی همون origin صفحهٔ اصلی اجرا میشه. یعنی کد داخلش میتونه parent.document، localStorage و کوکیها رو بخونه. نویسنده تو دموش نشون میده کد ساختهشده یه توکن سشن آزمایشی رو مستقیم از DOM صفحهٔ اصلی برمیداره. با sandbox="allow-scripts" همین خوندن خطای SecurityError میده، چون فریم یه opaque origin (originی که با هیچ originی جور نمیشه) میگیره.
تست دوم دربارهٔ فرار از فریمه: عوض کردن آدرس کل تب، باز کردن پاپآپ و ارسال فرم به یه سرور دلخواه. sandbox با فقط allow-scripts هر سه رو میبنده. نویسنده میگه اشتباه رایج اینه که آدم بعد از یه خطا، توکنهایی مثل allow-top-navigation یا allow-same-origin رو بیفکر اضافه کنه. هر توکن یه مجوز مشخصه و باید دلیل داشته باشه.
تست سوم چیزیه که خیلیها رو غافلگیر میکنه: فریم sandboxشده هنوز به شبکه دسترسی داره. با fetch() یا یه تصویر با آدرس خارجی میتونه داده رو تو URL بفرسته بیرون. جلوی این رو sandbox نمیگیره، بلکه یه CSP (یعنی سیاستی که مشخص میکنه صفحه از کجا منبع لود کنه) با default-src 'none' میگیره. البته CSP جلوی ناوبری خود فریم رو نمیگیره، پس این دو تا کنترل جدا و مکمل هم هستن.
نسخهٔ نهایی چند لایه داره. اول sandbox از صفر و فقط با allow-scripts، چون ترکیبش با allow-same-origin به کد اجازه میده sandbox خودش رو برداره. بعد یه دامنهٔ جدا برای محتوای کاربر، مثل کاری که CodePen با cdpn.io میکنه. CSP هم باید بهصورت تگ meta قبل از هر محتوای ساختهشده بیاد یا بهتر، بهصورت هدر:
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'">برای کانال postMessage (که معمولاً برای گزارش ارتفاع لازمه) نویسنده میگه هیچوقت رشتهٔ origin "null" رو تو allowlist نذار، چون همهٔ opaque originها همین رو گزارش میدن. هویت فرستنده رو با event.source چک کن و ساختار و مقدار پیام رو هم اعتبارسنجی کن. خودش یه بار برای لود تصویر از CDN شرکت img-src رو باز کرده و میگه هر شلکردنی باید یه تصمیم آگاهانه و قابل دفاع باشه.
نکات کلیدی:
- iframe با srcdoc و بدون sandbox روی origin صفحهٔ اصلی اجرا میشه و به DOM، localStorage و کوکیها دسترسی داره
- allow-scripts و allow-same-origin نباید با هم بیان، چون فریم میتونه sandbox خودش رو حذف کنه
- sandbox جلوی fetch() و درخواست تصویر به بیرون رو نمیگیره؛ برای این کار CSP با default-src 'none' لازمه
- همهٔ فریمهای sandboxشده origin رو "null" گزارش میدن، پس هویت فرستنده باید با event.source چک بشه
- یه دامنهٔ جدا مثل cdpn.io در CodePen باعث میشه حتی فرار کامل از sandbox به دادهای نرسه




