Brotli هم به RCE رسید؛ CVE-2026-111497 را همین امروز پچ کن
نویسنده: آرش لطیفی
آسیبپذیری Brotli در Node.js و زبانهای دیگر (HTTP2Shell) اجازه اجرای کد از راه دور میدهد — نسخههای پچشده و چکلیست بهروزرسانی.
TL;DR — باگ Brotli (CVE-2026-111497) که هفته پیش «Node2Shell» لقب گرفت، حالا HTTP2Shell شده: فقط Node.js نیست؛ Python، curl، Bun، Envoy و Istio را هم میگیرد. اگر Node 26/24/22 یا پکیج Brotli پایتون داری، همین امروز به نسخه پچشده ارتقا بده.
هفته پرماجرایی بود. سهشنبه ۲۱ اکتبر تیم Node.js اعلام کرد که دیکدر Brotli داخلی Node یک آسیبپذیری جدی دارد که با ورودی مخرب فشردهشده میتواند به خرابی حافظه، لو رفتن حافظه پروسه یا اجرای کد از راه دور برسد. جمعه معلوم شد قضیه خیلی بزرگتر از Node است — چون تقریبا هر نرمافزاری که HTTP را با فشردهسازی Brotli هندل میکند، از یک دیکدر مشترک استفاده میکند.
باگ دقیقا چیست؟
کد CVE-2026-111497 یک out-of-bounds write در دیکدر Brotli گوگل است که نسخههای ۱.۰.۳ تا ۱.۲.۰ را روی همه پلتفرمها میگیرد و امتیاز CVSS v4.0 آن ۹.۲ (Critical) است.
سادهاش این است: وقتی استریم Brotli خراب میرسد، دیکدر باید بلافاصله «فرمت نامعتبر» را ریجکت کند. اما در یک حالت خاص (invalid block switch) دیکدر فکر میکند فقط ورودی بیشتری لازم دارد و بایتها را به یک بافر داخلی ۸ بایتی اضافه میکند — تا سرریز. مهاجمی که بتواند داده Brotli کنترلشده بفرستد، میتواند حافظه پروسه را دستکاری کند.
نکته تلخ ماجرا: OpenAI این باگ را در فوریه ۲۰۲۶ پیدا کرده بود و ریشه آن در سورس Brotli هم همان موقع فیکس شده بود — ولی بهعنوان مسئله امنیتی شناسایی نشده بود و هیچ ریلیزی با آن منتشر نشده بود. یعنی هر پروژهای که Brotli را bundle کرده، باید خودش آپدیت بدهد. جالب اینکه گزارشدهنده در اطلاعیه Node.js هم تیم OpenAI Codex Security بود (Khai Tran و Sylvie Mayer).
چرا دوطرفه خطرناک است؟ چون هم کلاینت مخرب میتواند سرور پچنشده را بگیرد، هم سرور مخرب میتواند کلاینتی را که پاسخ فشرده قبول میکند بگیرد.
شعاع آسیب: فقط Node نیست
Aikido این موج را «HTTP2Shell» نامیده چون زبانها و ابزارهای زیادی از همان دیکدر استفاده میکنند:
- Node.js نسخههای 26.x، 24.x و 22.x — از Brotli داخلی
- Python — پکیجهای
Brotliوbrotlicffiکهrequests،httpxوaiohttpاگر نصب باشند خودکار لودشان میکنند - Bun، Envoy، Istio، curl/libcurl و هر باینریای که libbrotli را استاتیک لینک کرده
- خبر خوب:
mod_brotliآپاچی و Nginx بهصورت پیشفرض Brotli را decode نمیکنند
یک تله جدی هم هست: تا ۲۳ اکتبر دیتابیسهای advisory این CVE را به پکیجهای PyPI وصل نکرده بودند — یعنی pip-audit، Dependabot و Safety هنوز فلگشان نمیکردند. نمیتوانی روی اسکنر اتکا کنی؛ باید دستی چک کنی.
نسخههای پچشده
| پروژه | نسخه پچشده | | --- | --- | | Node.js | 22.23.4 / 24.22.1 / 26.12.1 | | Brotli (upstream) | 1.2.1 (یا 1.0.10 / 1.1.1 برای شاخههای قدیمی) | | Python: Brotli / brotlicffi | 1.2.1 / 1.2.1.0 | | Bun | 1.4.4 | | Envoy | 1.40.0 / 1.39.3 / 1.38.6 / 1.37.8 | | Istio | 1.29.9 / 1.30.6 / 1.31.2 |
چک کن و پچ کن
اگر اپ پایتون داری و Brotli واقعا لازم نیست، سریعترین راه مقاومسازی همین حالا، حذف کامل آن است:
httpx و requests بدون این پکیجها gzip و deflate را همچنان پشتیبانی میکنند — فقط اگر سروری بیهوده Brotli بفرستد ممکن است پاسخ ناخوانا شود.
- [ ]
node -vرا چک کردم و روی خط پچشده هستم - [ ] پکیجهای
Brotliوbrotlicffiپایتون را در همه محیطها (و داکر) چک/آپدیت کردم - [ ] ایمیجهای داکر را rebuild و ریاستارت کردم
- [ ] باینریهای کامپایلشده (Bun، استاتیک لینک) را با نسخه جدید بازساختم
- [ ] سرویسهای managed (ورکر، پلتفرم PaaS) را از ارائهدهنده پرسیدم که پچ شدهاند
- [ ] به آپدیتهای بعدی advisoryها سر زدم — هنوز در حال گسترش است
سه CVE دیگر در همان ریلیز Node
فقط Brotli نبود؛ اطلاعیه ۲۱ اکتبر Node چند آسیبپذیری high دیگر هم داشت که برای اپهای داخلی خطرناکند:
- CVE-2026-105482:
dns.resolve*()هاستنیمی که بایت NUL دارد را بیصدا truncate میکند — یعنی اعتبارسنجی allowlist دور زده میشود وattacker.example\0.trusted.exampleعملاً رکوردهایattacker.exampleرا برمیگرداند. - CVE-2026-105483: دور زدن بررسی hostname در TLS با ارقام fullwidth مثل
1۲۷.۰.۰.۱— گواهی DNS:127.0.0.1 برای IP نامعتبر قبول میشد. - CVE-2026-106069: IP با صفر ابتدایی مثل
0127.0.0.1— یکی octal میخواند یکی decimal، و گواهی IP اشتباه ولید میشد.
اگر تا دیروز فقط به فکر آپدیت Node برای Brotli بودی، این سه مورد دلیل کافی است که کل خط release را بروی.
Q: اپ من فقط JSON رندر میکند و ورودی کاربر را decompress نمیکند؛ آسیبپذیرم؟
احتمال سوءاستفاده مستقیم کم است ولی صفر نیست: هر کلاینتی که پاسخ HTTP فشرده با Brotli را قبول میکند در معرض سمت سرور مخرب است. در هر صورت آپدیت به نسخه پچشده هزینه ندارد — برو جلو.
Q: چرا اسکنر وابستگیهای من چیزی نگفت؟
چون تا ۲۳ اکتبر advisoryها CVE را به پکیجهای PyPI مپ نکرده بودند و برای Node هم فقط بعد از ریلیز اطلاعیه پر میشود. این مورد دقیقا نشان میدهد که برای CVEهای تازه، اسکنر «بعد از ماجرا» است.
Q: تا آپدیت کامل چکار کنم؟
اولویت: Node را به خط پچشده ببر. در پایتون اگر Brotli اجباری نیست حذفش کن. اگر سرویسی پچ ندارد و Brotli decode میکند، تا دسترسی پچ، decoding را غیرفعال کن.