CVE-2026-111497 ช่องโหว่ Brotli ใน PHP สำหรับ Windows

php.net ออก PHP สำหรับ Windows ชุดใหม่ 8.5.12-1, 8.4.27-1, 8.3.36-1 และ 8.2.35-1 ที่มาพร้อม Brotli 1.2.1 แก้ CVE-2026-111497 เลขเวอร์ชันของ PHP ไม่เปลี่ยน ต้องดูที่ -1 ต่อท้าย และแอป Laravel ที่เรียก API ด้วย Http ก็คลายข้อมูล Brotli อัตโนมัติอยู่แล้ว

เผยแพร่
เวลาอ่าน
3 นาที
สรุปจาก
Eric L. Barnes · phpnews.net
ในโพสต์นี้ 5 หัวข้อ
  1. Brotli อยู่ใน PHP บน Windows ตรงไหน
  2. แอป Laravel ที่เรียก API ด้วย Http เปิดการคลายข้อมูลไว้แล้ว
  3. เครื่องแบบไหนต้องอัปเดต
  4. โหลด build ใหม่มาแทนตัวเดิม
  5. ถ้ายังอัปเดตไม่ได้ทันที

Brotli อยู่ใน PHP บน Windows ตรงไหน

Brotli เป็นวิธีบีบอัดข้อมูลแบบเดียวกับ gzip ที่เว็บใช้ส่งหน้าเว็บให้เล็กลง เครื่องที่รับข้อมูลต้องคลายกลับก่อนอ่าน

ใน zip ของ PHP สำหรับ Windows มีไฟล์ brotlidec.dll วางอยู่ข้าง extension cURL เพื่อให้ cURL คลายข้อมูล Brotli ได้ ตัวที่มีช่องโหว่คือส่วนคลายข้อมูลนี้ ตามประกาศของ php.net โค้ด PHP จะไปถึงส่วนนี้ได้เมื่อเปิดให้ cURL คลายข้อมูลที่ตอบกลับมาเอง

ข้อมูลที่ทำขึ้นมาเฉพาะทำให้ PHP เขียนข้อมูลเลยขอบเขตของหน่วยความจำ ตามข้อมูลของ CVE ผลอาจเป็นได้ตั้งแต่ process ล่ม ข้อมูลในหน่วยความจำรั่ว ไปจนถึงรันโค้ดได้ ช่องโหว่นี้แยกจาก PHP2Shell สองตัวที่แก้ไปเมื่อ 21 ต.ค. ซึ่งอยู่ในตัว PHP เอง

แอป Laravel ที่เรียก API ด้วย Http เปิดการคลายข้อมูลไว้แล้ว

ประกาศบอกว่า cURL ปิดการคลายข้อมูลอัตโนมัติไว้เป็นค่าเริ่มต้น แต่ไลบรารีที่ใช้เรียก HTTP เปิดให้เองได้ ซึ่ง Guzzle ที่อยู่ใต้ Http::get() ของ Laravel ก็เป็นแบบนั้น Guzzle ตั้ง decode_content เป็น true ไว้เป็นค่าเริ่มต้น แล้วสั่ง cURL ให้เปิดตัวคลายข้อมูลทุกแบบที่มี ซึ่งรวม Brotli ด้วย (ดูได้ใน CurlFactory.php ของ guzzlehttp/guzzle)

ดังนั้นแอป Laravel บน Windows ที่เรียก URL ภายนอก ก็มีทางไปถึง brotlidec.dll ได้ทันทีที่เครื่องปลายทางตอบกลับมาเป็น Brotli จุดที่เสี่ยงที่สุดคือโค้ดที่เรียก URL ที่ผู้ใช้ใส่มาเอง เช่น ดึงรูปจากลิงก์ ทำ link preview หรือ webhook ที่ให้ลูกค้าตั้ง URL เองได้ เพราะคนนอกเลือกได้ว่าจะให้เครื่องไหนตอบ ส่วนการเรียก API ของผู้ให้บริการที่เรารู้จักก็เสี่ยงน้อยกว่า แต่ไม่ถึงกับศูนย์

เครื่องแบบไหนต้องอัปเดต

ที่ที่รัน PHP ต้องทำอะไร
Windows Server ที่รัน PHP กับ IIS หรือ Apache โหลด build -1 ของรุ่นที่ใช้อยู่มาแทน แล้วรีสตาร์ต IIS, Apache หรือ PHP-CGI และ queue worker
เครื่อง dev บน Windows (XAMPP, Laragon, WAMP) อัปเดตด้วย แม้จะเป็นแค่เครื่อง dev เพราะโค้ดที่เราเขียนก็เรียก API ภายนอกจากเครื่องนี้
Linux (Ubuntu, Debian, ondrej PPA, Docker image ทางการ) build ชุดนี้ไม่เกี่ยว PHP บน Linux ใช้ cURL และ Brotli ของระบบ ให้ติดตามแพตช์ของ Brotli จาก OS แทน
PHP 8.1 บน Windows ไม่มี build ใหม่ ยังเป็น build ของ ธ.ค. 2025 และไม่ได้แพตช์ PHP2Shell ด้วย ควรขึ้นรุ่นที่ยังมี support

โหลด build ใหม่มาแทนตัวเดิม

  1. เปิดหน้าดาวน์โหลดสำหรับ Windows แล้วเลือกรุ่นเดียวกับที่ใช้อยู่ เช่น 8.3 ก็ใช้ 8.3.36-1
  2. เลือกให้ตรงกับของเดิมทั้งสองเรื่อง คือ x64 หรือ x86 และ Thread Safe หรือ Non Thread Safe ถ้ารันกับ Apache แบบ module มักเป็น Thread Safe ส่วน IIS ที่รันผ่าน FastCGI มักเป็น Non Thread Safe ถ้าไม่แน่ใจ ให้ดูบรรทัด Thread Safety ใน phpinfo() ของเครื่องเดิม
  3. แตกไฟล์ไปวางแทนโฟลเดอร์ PHP เดิม โดยเก็บ php.ini ตัวเดิมไว้ แล้วรีสตาร์ตทุก process ที่ใช้ PHP

ถ้าใช้ Laragon ปกติเราแตก zip ไปไว้ใน bin\php แล้วเลือกรุ่นใหม่จากเมนูได้เลย ส่วน XAMPP ไม่ได้ออกรุ่นตามทุกแพตช์ของ PHP ทางที่เร็วกว่าคือแทนโฟลเดอร์ php เองแบบเดียวกัน

เลข php -v ของ build -1 ยังขึ้นเป็น 8.3.36 เหมือนเดิม เพราะเป็นโค้ด PHP ชุดเดียวกัน ต่างกันแค่ไลบรารีที่ใส่มาด้วย เรื่องนี้คล้ายกับเลขเวอร์ชัน PHP ของ Ubuntu ที่เลขหลักไม่เปลี่ยนแต่แพตช์เปลี่ยน วิธีที่แน่นอนที่สุดคือจดไว้ว่าโหลด zip ตัวไหนมาลงเมื่อไร

ถ้ายังอัปเดตไม่ได้ทันที

ช่วงที่ยังลง build ใหม่ไม่ได้ ให้ปิดทางที่ข้อมูลจากคนนอกจะเข้ามาถึงตัวคลาย Brotli ก่อน

  • ปิด decode_content ของ Guzzle ในโค้ดที่เรียก URL ที่ผู้ใช้ใส่มาเอง เช่น Http::withOptions(['decode_content' => false]) cURL จะไม่คลายข้อมูลที่บีบอัดมาให้ แต่โค้ดส่วนนั้นต้องรับมือกับข้อมูลที่ยังบีบอัดอยู่เอง
  • หยุดฟีเจอร์ที่ดึง URL ตามที่ผู้ใช้ส่งมาไว้ชั่วคราว ถ้าระบบมี

ทั้งสองข้อเป็นแค่ทางกันระหว่างรอ ทางแก้จริงคือ build -1

อ่านต่อ

ล่าสุด

ดูทั้งหมด →