کشف آسیبپذیری روز صفر در مرورگر Ladybird
خلاصهٔ کاملتر
یه محقق امنیتی موفق شده یه آسیبپذیری جدی از نوع Use-After-Free (UAF) توی مرورگر متنباز Ladybird پیدا کنه که بهش اجازه میده کد دلخواه رو از راه دور اجرا کنه. این باگ الان پچ شده و advisory امنیتیش با کد GHSA-w89h-j2xg-c457 منتشره.
ریشه مشکل توی نحوه مدیریت حافظه موتور جاوااسکریپت LibJS هست. سه ساختار داده مجزا یعنی AK::ByteBuffer که حافظه خام رو نگه میداره، JS::ArrayBuffer که wrapper سطح بالاتره، و JS::TypedArrayBase که یه pointer کششده به حافظه داره، باید همیشه با هم همگام باشن. وقتی این همگامسازی به هم میریزه، فاجعه شروع میشه.
مشکل اصلی اینه که وقتی یه SharedArrayBuffer بر اساس مشخصات WebAssembly grow میکنه، حافظه قدیمی آزاد میشه ولی pointer ذخیرهشده داخل TypedArray هنوز به همون آدرس قدیمی اشاره میکنه. این یعنی داریم به حافظهای دسترسی پیدا میکنیم که آزاد شده.
جالبترین بخش ماجرا اینه که مفسر دستورالعملهای بهینهشده Ladybird (AsmInterpreter) یه fast path داره که مستقیماً از این pointer کششده استفاده میکنه و هیچ چک validationای روی اعتبار اون نداره. اگه pointer نال باشه میره سراغ slow path، ولی اگه نال نباشه و stale باشه؟ مستقیم میره سراغ حافظه آزادشده.
نکته عجیبتر اینه که ابزار معروف ASAN (که معمولاً برای پیدا کردن همین نوع باگها استفاده میشه) این مشکل رو شناسایی نمیکنه. دلیلش اینه که دسترسی به حافظه از طریق assembly دستنویس بهینهشده انجام میشه و ASAN از اون خبردار نمیشه.
محقق برای اثبات اکسپلویت، از تکنیکهای پیشرفتهای که توی اکسپلویتهای V8 هم استفاده میشه بهره برده. اول با spray کردن آرایههای جاوااسکریپت حافظه آزادشده رو reclaim میکنه، بعد با پیدا کردن همپوشانی بین TypedArray دانگلینگ و اشیاء دیگه، primitive های خوندن و نوشتن دلخواه در حافظه رو میسازه.
ساختار NaN-boxing که Ladybird برای ذخیره مقادیر جاوااسکریپت استفاده میکنه هم توی این اکسپلویت نقش داره. هر Value اوبجکت ۶۴ بیته و آدرس واقعی سل رو توی ۴۸ بیت پایینی ذخیره میکنه. محقق با خوندن و نوشتن این ساختار، primitive های addrof و fakeobj میسازه که بعداً میشه ازشون برای خوندن و نوشتن دلخواه هر آدرسی توی حافظه استفاده کرد.
اما نکته مثبت ماجرا اینه که تیم توسعه Ladybird خیلی سریع واکنش نشون داد و چند روز بعد از گزارش، وصله امنیتی رو منتشر کرد. این باگ نشون میده که حتی موتورهای جاوااسکریپت مدرن چقدر میتونن در معرض آسیبپذیریهای پیچیده باشن، مخصوصاً وقتی بهینهسازی دستی (مثل assembly دستنویس) با مدیریت دقیق حافظه ترکیب میشه.
نکات کلیدی:
- آسیبپذیری UAF در مرورگر Ladybird توی موتور جاوااسکریپت LibJS بود
- باگ از طریق grow کردن SharedArrayBuffer در WebAssembly قابل تریگر شدنه
- fast path مفسر assembly دستنویس هیچ چکی روی اعتبار pointer کششده نداره
- ASAN این باگ رو شناسایی نمیکنه چون دسترسی از طریق assembly انجام میشه
- اکسپلویت منجر به اجرای کد از راه دور میشه
- باگ گزارش شد و در چند روز پچ شد (GHSA-w89h-j2xg-c457)




