کابوس امنیتی SVG در اسکرچ؛ از XSS تا نشت HTTP
خلاصهٔ کاملتر
اسکرچ (Scratch)، پلتفرم محبوب آموزش برنامهنویسی، یه تاریخچهی طولانی و دردناک از آسیبپذیریهای مرتبط با SVG داره. ریشهی اصلی این مشکلات اینه که اسکرچ محتوای SVG ساختهشده توسط کاربر رو مستقیماً پارس میکنه؛ محتوایی که میتونه کاملاً توسط یه مهاجم کنترل بشه.
در اولین تلاش برای حل این مشکل، از یه Regex ساده برای حذف تگهای اسکریپت استفاده شد. اما این رویکرد خیلی زود شکست خورد؛ چون مهاجمها میتونستن با بزرگ کردن حروف تگ، مثل SCRIPT به جای script، فیلتر رو دور بزنن. این باگ به عنوان CVE-2020-7750 ثبت شد و نشون داد که Regex ابزار مناسبی برای پارس HTML/SVG نیست.
بعد از این، تیم اسکرچ به سمت DOMPurify رفت که یه کتابخانهی تخصصی برای پاکسازی HTML و SVGه. اما ماجرا اینجا هم تموم نشد؛ چون SVG میتونه از طریق CSS به منابع خارجی درخواست بزنه و اطلاعات رو نشت بده. پاکسازی CSS داخل SVG خودش یه بازی بیپایانه.
TurboWarp که یه فورک از اسکرچه، رویکرد متفاوتی انتخاب کرد: به جای اینکه بخواد همهی راههای ممکن برای سوءاستفاده از SVG رو بشناسه و مسدود کنه، کل SVG رو داخل یه iframe ایزولهشده قرار میده. این iframe یه Content Security Policy سختگیرانه داره که همهی اسکریپتها رو بلاک میکنه و فقط بارگذاری منابع امن از data URL رو مجاز میدونه.
این رویکرد چند مزیت مهم داره: اول اینکه مرورگر خودش کار سخت رو انجام میده و دیگه نیازی نیست TurboWarp همهی ترفندهای ممکن رو بشناسه. دوم اینکه SVG نمیتونه روی صفحهی اصلی تأثیر بذاره؛ مثلاً حتی اگه تمام استایلهای صفحه رو دستکاری کنه، فقط داخل iframe تأثیر میذاره. سوم اینکه برای APIهای جدیدی که در آینده به مرورگرها اضافه میشن هم بهصورت خودکار کار میکنه.
جالبترین بخش ماجرا اینه که بعد از انتشار این مقاله، نویسنده از Claude Opus (مدل هوش مصنوعی آنتروپیک) خواست تا ریپوی اسکرچ رو بررسی کنه و دنبال باگ بگرده. Claude دو مشکل پیدا کرد: یکی اینکه image-set در CSS پاکسازی نمیشه و میتونه باعث نشت HTTP بشه. دومی یه باگ جالبتر مربوط به CSS nesting بود.
CSS nesting دو شکل داره: یکی با پیشوند & و یکی بدون پیشوند (که بهش "relaxed syntax" میگن). کتابخانهی css-tree که اسکرچ ازش برای پارس CSS استفاده میکنه، نسخهی اول رو درست پارس میکنه و اسکرچ میتونه اون رو پاکسازی کنه. اما نسخهی دوم (بدون &) رو به صورت "raw text" پارس میکنه و کد پاکسازی اسکرچ اصلاً بهش نگاه نمیکنه! این یعنی یه مهاجم میتونه از طریق CSS nesting relaxed، درخواستهای HTTP به سرور دلخواهش بزنه.
این باگ هنوز پچ نشده و issue مربوطه در css-tree از دسامبر ۲۰۲۳ باز مونده. نویسنده معتقده که اتکا به css-tree به عنوان یه پارسر کامل و بینقص، یه مسیر بیامیده که ادامهاش فقط آسیبپذیریهای جدید به بار میاره. رویکرد sandbox مبتنی بر iframe که TurboWarp استفاده میکنه این باگ رو قبل از اینکه کشف بشه بلاک کرده بود.
نکات کلیدی:
- استفاده از Regex برای پارس SVG/HTML کاملاً اشتباهه و بهراحتی دور زده میشه
- DOMPurify هم برای CSS داخل SVG کافی نیست چون پارسر CSS (css-tree) باگهای شناختهشده داره
- رویکرد ایزولهکردن SVG داخل iframe با CSP سختگیرانه، راهحل بسیار مطمئنتریه
- Claude Opus یه آسیبپذیری واقعی و جدید در CSS nesting relaxed syntax پیدا کرد
- این باگ CSS nesting هنوز در اسکرچ پچ نشده ولی TurboWarp از ابتدا در برابرش ایمن بوده
- css-tree به عنوان پارسر CSS قابل اعتماد نیست و ۴۸ issue باز داره




