บั๊ก Brotli CVE-2026-111497 ร้ายแรงแค่ไหน และทำไมสแกนผ่านยังไม่พอ?
โดย Nokka (นก-กา) | ตรวจข้อมูล 24 ต.ค. 2026 บทความนี้เขียนโดย AI (deepseek-v4.1-flash · ผู้ให้บริการโมเดล: ollama-cloud) ผ่าน Hermes Agent ภายใต้การควบคุมและตรวจสอบคุณภาพโดยมนุษย์ - Nokka (นก-กา) ต้นสัปดาห์นี้มีข่าวช
โดย Nokka (นก-กา) | ตรวจข้อมูล 24 ต.ค. 2026
บทความนี้เขียนโดย AI (deepseek-v4.1-flash · ผู้ให้บริการโมเดล: ollama-cloud) ผ่าน Hermes Agent ภายใต้การควบคุมและตรวจสอบคุณภาพโดยมนุษย์ - Nokka (นก-กา)
ต้นสัปดาห์นี้มีข่าวช่องโหว่ที่คนไทยอาจมองข้าม เพราะมันไม่ได้อยู่ในแอปที่ใครใช้ตรง ๆ แต่ซ่อนอยู่ในไลบรารีบีบอัดข้อมูลที่แทบทุกภาษาโปรแกรมใช้
ชื่อมันคือ CVE-2026-111497 หรือที่ Aikido เรียกกันว่า node2shell และทีมเดียวกันตั้งชื่อภาคต่อว่า HTTP2Shell [1]
คะแนนความรุนแรงที่ศูนย์ประสานงานของ Google ให้ไว้คือ 9.2 จาก 10 ระดับ critical [2]
และส่วนที่ผมคิดว่าสำคัญที่สุดสำหรับคนทำงานสายนี้คือ เรื่องของ "เวลากับฐานข้อมูล" เพราะสถานะการถูกตรวจจับของช่องโหว่นี้เปลี่ยนไปภายในสองวัน และคนที่อ่านข่าวช้ากว่าหนึ่งวันอาจได้ข้อสรุปผิด
เกิดอะไรขึ้น
วันที่ 21 ตุลาคม 2026 ทีม Node.js เปิดเผยช่องโหว่ในตัวถอดรหัส Brotli ที่มาพร้อมกับ Node.js ทำให้โปรเซสที่คลายข้อมูล Brotli จากผู้โจมตีสามารถรั่วหน่วยความจำหรือรันโค้ดได้ [1][3]
วันรุ่งขึ้น ฝั่ง Python ออกประกาศว่าแพ็กเกจ PyPI สองตัวคือ brotli และ brotlicffi คอมไพล์ตัวถอดรหัส Brotli ตัวเดียวกับที่ Node.js ใช้ และได้รับผลกระทบเช่นกัน [1]
NVD ออกบันทึก CVE เมื่อวันที่ 22 ตุลาคม 2026 โดยระบุว่าช่องโหว่อยู่ในไฟล์ c/dec/decode.c กระทบ Brotli เวอร์ชัน 1.0.3 ถึง 1.2.0 ทุกแพลตฟอร์ม และผู้โจมตีระยะไกลที่ไม่ต้องยืนยันตัวตนสามารถส่งสตรีมที่สร้างมาเป็นพิเศษเพื่อทำอันตรายได้ [2]
บั๊กอยู่ตรงไหน
จุดที่ตรรกะสองค่าทำให้สับสน
จุดพังอยู่ในฟังก์ชัน DecodeBlockTypeAndLength() ซึ่งจัดการการสลับบล็อกของสตรีม Brotli [1]
ในเวอร์ชันที่พัง ฟังก์ชันนี้คืนค่าตรรกะง่าย ๆ สองค่า คือจริงกับเท็จ แต่ค่าเท็จมีความหมายได้สองอย่าง คือ "ข้อมูลผิดรูป" หรือ "ยังต้องการข้อมูลเพิ่ม" [1]
ผู้เรียกจึงแยกสองกรณีนี้ไม่ออก และเมื่อสตรีมที่สร้างมาอย่างจงใจทำให้การสลับบล็อกล้มเหลวในเส้นทางที่เร็ว ตัวถอดรหัสก็เดินต่อด้วยสถานะเดิม แล้วเขียนเกินขอบหน่วยความจำ [1]
แพตช์ต้นทางคือคอมมิต 0ed4268 ใน repo google/brotli ซึ่งเปลี่ยนฟังก์ชันให้คืนรหัสข้อผิดพลาดและเพิ่มรหัสใหม่ BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH ค่า -17 [1]
ถ้าคุณไม่คุ้นศัพท์พวกนี้ ไม่เป็นไรครับ สาระมีแค่สองบรรทัด คือบั๊กนี้ทำให้โปรแกรมเขียนข้อมูลเกินพื้นที่ที่จัดไว้ และผลที่ตามมาคืออาจรันโค้ดของคนอื่นได้
ทำไมอันตรายกว่าที่ชื่อบอก
ชื่อ node2shell ทำให้คนคิดว่าเป็นเรื่องของ Node.js เท่านั้น แต่ชื่อใหม่ที่ Aikido ตั้งว่า HTTP2Shell บอกความจริงอีกด้าน [1]
ความเสี่ยงเกิดได้สองทาง ทางแรกคือเซิร์ฟเวอร์ที่แกะข้อมูลบีบอัดซึ่งผู้ใช้ส่งเข้ามา ทางที่สองคือไคลเอนต์ที่รับข้อมูลบีบอัดจากเซิร์ฟเวอร์ซึ่งไม่น่าไว้ใจ [1]
แปลว่าโปรแกรมที่แค่เรียก API ภายนอกแล้วรับ response แบบ Brotli ก็อยู่ในเส้นทางโจมตีได้ ถ้าไลบรารีที่ใช้ถอดรหัสยังไม่ได้แพตช์
จุดนี้เองที่ทำให้มันไม่ใช่ปัญหาของคนเขียนเซิร์ฟเวอร์อย่างเดียว แต่เป็นปัญหาของทุกคนที่ติดตั้งไลบรารีนั้นโดยไม่รู้ตัว
ใครเสี่ยงบ้าง
เงื่อนไขสั้น ๆ คือถ้าสภาพแวดล้อมใดมีอย่างใดอย่างหนึ่งนี้อยู่ คุณอยู่ในข่าย [1][4]
brotli 1.0.3 - 1.2.0 (แพ็กเกจ PyPI · แก้ที่ 1.2.1)
brotlicffi 1.0.3 - 1.2.0.x (แพ็กเกจ PyPI · แก้ที่ 1.2.1.0)
Brotli 1.0.3 - 1.2.0 (ไลบรารีต้นทาง ทุกภาษา)
ช่วงเวอร์ชันนี้กว้างกว่าที่หลายคนคิด เพราะ brotlicffi รุ่นเก่าอย่าง 1.0.9.x หรือ 1.1.0.0 ก็อยู่ในข่ายด้วย ไม่ใช่แค่ 1.2.0.x [4]
สิ่งที่ทำให้เรื่องนี้น่ากังวลคือ HTTP client ยอดนิยมอย่าง requests, httpx และ aiohttp จะโหลดแพ็กเกจ Brotli ขึ้นมาอัตโนมัติ ถ้ามันมีอยู่ในเครื่อง [1]
และมีแพ็กเกจอย่าง Scrapy ที่ติดตั้ง Brotli มาเป็น dependency ให้เอง [1]
จำนวนดาวน์โหลดของแพ็กเกจ brotli บน PyPI อยู่ที่ประมาณ 82.8 ล้านครั้งต่อเดือน [1] ซึ่งบอกขนาดของพื้นที่ผิวได้ดี
เรื่องของเวลากับฐานข้อมูลสแกน
สองวันที่ต้องแยกให้ออก
นี่คือส่วนที่ผมอยากให้จำไปใช้งานจริง เพราะมันเปลี่ยนไปเร็วมาก
ช่วง 21 ถึง 22 ตุลาคม ฐานข้อมูลยังไม่ผูกช่องโหว่นี้เข้ากับแพ็กเกจ PyPI ทั้งสองตัว บทความของ Aikido ที่ลงวันที่ 23 ตุลาคมจึงเขียนว่า pip-audit, Dependabot และ Safety ยังไม่แจ้งเตือน [1]
ตั้งแต่วันที่ 23 ตุลาคมเป็นต้นมา สถานะเปลี่ยนแล้ว
- PyPA ออกบันทึก PYSEC-2026-4322 ของ
brotliและ PYSEC-2026-4323 ของbrotlicffiและรุ่นที่แก้คือ 1.2.1 กับ 1.2.1.0 [5][6] ส่วนช่วง 1.0.3 ถึงรุ่นที่แก้มาจากระเบียน GHSA [4] - GitHub Advisory Database ปรับปรุง GHSA-9v8h-qqgm-4m35 เมื่อวันที่ 23 ตุลาคม (เผยแพร่ครั้งแรก 22 ตุลาคม) โดยผูกช่องโหว่นี้เข้ากับแพ็กเกจ
brotliและbrotlicffiทั้งคู่ [4] - PyPI เองเริ่มคืนข้อมูลช่องโหว่ในหน้าข้อมูลแพ็กเกจแล้ว เช่น
brotli1.2.0 มีฟิลด์vulnerabilitiesระบุ PYSEC-2026-4322 และ GHSA-9v8h-qqgm-4m35 [5]
ผลคือ pip-audit ซึ่งอ่านข้อมูลช่องโหว่จาก PyPI จะเริ่มจับได้แล้ว รวมถึง Dependabot ที่อ่าน GitHub Advisory
ส่วนที่ยังว่างอยู่คือ NVD ซึ่งยังขึ้นสถานะ Awaiting Analysis และยังไม่มี CPE mapping [2]
บทเรียนที่ยังใช้ได้
เรื่องนี้สอนว่า "สแกนผ่าน" กับ "ปลอดภัย" เป็นคนละคำตอบ เพราะเครื่องมือสแกนอ่านจากฐานข้อมูล และฐานข้อมูลก็มีเวลาหน่วงของมัน
ถ้าคุณสแกนเมื่อวานแล้วผ่าน วันนี้ควรสแกนใหม่
วิธีเช็กในเครื่องคุณ
คำสั่งพวกนี้ใช้ได้กับโปรเจกต์ Python ทั่วไปครับ
# ดูเวอร์ชันที่ติดตั้งอยู่จริง
python -m pip show brotli brotlicffi
# ตรวจทั้ง environment แบบเร็ว
python - <<'PY'
import importlib.metadata as m
for name in ("brotli", "brotlicffi"):
try:
print(name, m.version(name))
except m.PackageNotFoundError:
print(name, "not installed")
PY
# อัปเดตเป็นเวอร์ชันที่แพตช์แล้ว
python -m pip install --upgrade "brotli>=1.2.1" "brotlicffi>=1.2.1.0"
# สแกนด้วยเครื่องมือ (ควรอัปเดตฐานข้อมูลก่อน)
python -m pip_audit
คำสั่ง pip install ข้างบนแก้เฉพาะ environment ที่คุณกำลังรันอยู่ ถ้าคุณมีหลาย venv, system python, pyenv หรือ container หลายตัว ต้องทำซ้ำในทุกที่ [1]
และถ้าใช้ Docker อย่าลืม rebuild image ใหม่ เพราะการอัปเดตบนเครื่อง host ไม่ช่วยอะไรกับ image ที่ build ไว้แล้ว [1]
ถ้ายังอัปเดตไม่ได้ทันที
มีมาตรการชั่วคราวที่พอช่วยลดพื้นที่ผิวได้ [1]
- ถอน Brotli ออก ถ้าไม่จำเป็นจริง ๆ เพราะเมื่อไม่มี decoder ไคลเอนต์มักถอยไปใช้ gzip หรือ deflate แทน
- ปฏิเสธ Brotli ที่ขอบระบบ เช่นที่ reverse proxy หรือ CDN
-
ปิดการถอดรหัส Brotli ขาออก โดยถอด
brออกจากAccept-Encodingและปิดการ decode response ของ Brotli ในไลบรารีที่ใช้ [1]
แต่มีกับดักที่ต้องรู้ คือ การแก้ Accept-Encoding อย่างเดียวไม่พอ เพราะเซิร์ฟเวอร์ที่ประสงค์ร้ายยังส่งข้อมูลแบบ Brotli มาได้ไม่ว่าเราจะขออะไร และ urllib3 เลือกตัวถอดรหัสจากหัว Content-Encoding ของ response [1]
แปลว่าการตั้งค่าฝั่งที่เราขอ ไม่ได้ป้องกันฝั่งที่เขาส่ง
บทเรียนที่ใหญ่กว่าตัวบั๊ก
เรื่องนี้มีรายละเอียดที่ผมคิดว่าน่าสนใจกว่าตัว CVE
บั๊กนี้ถูกพบโดย OpenAI ตั้งแต่เดือนกุมภาพันธ์ 2026 และแจ้งว่าเป็น remote code execution ที่ไม่ต้องยืนยันตัวตน [1]
ตัวโค้ดต้นทางถูกแก้ตั้งแต่เดือนกุมภาพันธ์เช่นกัน แต่ตอนนั้นยังไม่ถูกมองว่าเป็นช่องโหว่ด้านความปลอดภัย จึงไม่มีรีลีสไหนออกมาในช่วงนั้น และกว่าจะมีรุ่นที่บรรจุแพตช์ก็ผ่านมาหลายเดือน [1]
ผลคือทุกโปรเจกต์ที่ฝัง Brotli ไว้ในผลิตภัณฑ์ของตัวเอง ต้องออกรีลีสของตัวเองเพื่อส่งแพตช์ต่อให้ผู้ใช้
นี่คือธรรมชาติของไลบรารีระดับล่างที่ถูกฝังไว้ในทุกภาษา เมื่อปลายน้ำต้องรอต้นน้ำ ปลายน้ำทั้งโลกก็ขยับช้ากว่าที่ควร
ตัวอย่างสถานการณ์ที่พบบ่อย
ลองนึกภาพบริการเล็ก ๆ ที่รับ JSON จากลูกค้า แล้วใช้ httpx เรียก API ของพาร์ตเนอร์เพื่อเติมข้อมูลก่อนตอบกลับ
ถ้าเครื่องนั้นมีแพ็กเกจ brotli ติดมาพร้อมไลบรารีอื่น และพาร์ตเนอร์หรือคนกลางตอบกลับด้วย Brotli ที่สร้างมาเป็นพิเศษ ตัวถอดรหัสในเครื่องคุณคือจุดที่พัง
คุณไม่ได้เขียนโค้ดถอดรหัสเอง ไม่ได้ตั้งใจใช้ Brotli ด้วยซ้ำ แต่มันอยู่ใน dependency tree
ใครควรทำอะไรก่อน
ถ้าคุณมีระบบที่รับข้อมูลจากภายนอกหรือเรียก API ภายนอกเป็นประจำ ผมจัดลำดับให้แบบนี้
- เช็กก่อนว่ามี
brotliหรือbrotlicffiในเครื่องหรือไม่ - อัปเดตเป็น 1.2.1 หรือ 1.2.1.0 แล้ว rebuild image
- ถ้าอัปเดตทันทีไม่ได้ ให้ถอนออกหรือปิด Brotli ที่ขอบระบบไปก่อน
- รันสแกนซ้ำหลังอัปเดตฐานข้อมูล และยืนยันเวอร์ชันจริงในเครื่อง ไม่ใช่ดูแค่ผลสแกน
และถ้าคุณเป็นคนดูแลไลบรารีที่ฝัง Brotli อยู่ งานของคุณคือออกรีลีสใหม่ ไม่ใช่รอต้นน้ำ
REF
[1] Aikido Security (23 ต.ค. 2026, แก้ล่าสุด 24 ต.ค. 2026) · Node2Shell evolves to HTTP2Shell: Brotli flaw CVE-2026-111497. https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497
[2] NVD · CVE-2026-111497 (เผยแพร่ 22 ต.ค. 2026 · CVSS 4.0 base 9.2 critical · สถานะ Awaiting Analysis). https://nvd.nist.gov/vuln/detail/CVE-2026-111497
[3] Node.js (ต.ค. 2026) · October 2026 Security Releases. https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
[4] GitHub Advisory Database (22 ต.ค. 2026) · GHSA-9v8h-qqgm-4m35. https://github.com/advisories/GHSA-9v8h-qqgm-4m35
[5] PyPI (เข้าถึง 24 ต.ค. 2026) · แพ็กเกจ brotli พร้อมข้อมูลช่องโหว่ PYSEC-2026-4322 และ GHSA-9v8h-qqgm-4m35. https://pypi.org/project/Brotli/
[6] OSV (23 ต.ค. 2026) · PYSEC-2026-4322 และ PYSEC-2026-4323. https://osv.dev/vulnerability/PYSEC-2026-4322
Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.