บทความทั้งหมด

PHP · ช่องโหว่ · CVE · การรันโค้ดจากระยะไกล · การอัปเดต · การจัดการเหตุการณ์

ช่องโหว่ร้ายแรงใน PHP – อัปเดตทันที (CVE-2026-109618 และ CVE-2026-109619)

ช่องโหว่ร้ายแรงสองรายการใน PHP ค่า CVSS 9,2 เปิดทางให้รันโค้ดจากระยะไกลโดยไม่ต้องยืนยันตัวตน แก้ไขแล้วใน PHP 8.5.12, 8.4.27, 8.3.36 และ 8.2.35 – วิธีตรวจสอบสถานะและแก้ไขวันนี้

เผยแพร่ 2 นาทีในการอ่าน

เมื่อวันที่ 20 ตุลาคม โครงการ PHP ประกาศเตรียมออกเวอร์ชันความปลอดภัยสำหรับช่องโหว่ร้ายแรงสองรายการ วันที่ 21 ตุลาคม เวลา 13:30 UTC แพตช์ถูกเผยแพร่ ทั้งสองช่องโหว่เปิดทางให้ รันโค้ดจากระยะไกลโดยไม่ต้องยืนยันตัวตน ด้วยคะแนน CVSS 9,2 และโค้ด proof-of-concept ก็แพร่กระจายอยู่แล้ว

นี่ไม่ใช่ช่องโหว่ที่วางแผนไว้ในรอบบำรุงรักษาครั้งถัดไป แต่เป็นช่องโหว่ที่ต้องแก้ไขวันนี้

สรุปสั้น

  • อัปเดตเป็น PHP 8.5.12, 8.4.27, 8.3.36 หรือ 8.2.35
  • PHP ทุกตัวที่ให้บริการคำขอผ่านเว็บได้รับผลกระทบ – PHP-FPM, mod_php, php-cgi, FrankenPHP และ LiteSpeed
  • คำขอเดียวที่ไม่ต้องยืนยันตัวตนอาจเพียงพอ และโจมตีได้ก่อนที่โค้ดแอปพลิเคชันของคุณจะทำงานด้วยซ้ำ
  • โค้ด PoC เป็นสาธารณะแล้ว คาดการณ์การสแกนเป็นวงกว้างภายในไม่กี่ชั่วโมง ไม่ใช่ไม่กี่สัปดาห์
  • หากยังแก้ไขไม่ได้ทันที: ตัดการเข้าถึงบริการที่เปิดสู่อินเทอร์เน็ต จนกว่าแพตช์จะถูกติดตั้งและตรวจสอบแล้ว

เกิดอะไรขึ้น

วันที่ 20 ตุลาคม โครงการ PHP แจ้งว่ากำลังเตรียมออกเวอร์ชันความปลอดภัย วันถัดมา 21 ตุลาคม เวลา 13:30 UTC แพตช์ถูกเผยแพร่พร้อมกันในสี่เวอร์ชัน คือ 8.5.12, 8.4.27, 8.3.36 และ 8.2.35 CERT-EU ออกประกาศเตือนในวันเดียวกันและเรียกร้องให้องค์กรอัปเดตทันที

การแก้ไขอย่างรวดเร็วเป็นสิ่งดี แต่การที่คำอธิบายทางเทคนิคกลายเป็นสาธารณะในเวลาเดียวกัน หมายความว่าระยะเวลาตั้งแต่ “มีแพตช์แล้ว” จนถึง “ผู้โจมตีเริ่มลอง” วัดกันเป็นชั่วโมง

ช่องโหว่เหล่านี้ทำอะไรจริง ๆ

CVE-2026-109618 – ความเสียหายของหน่วยความจำที่ขอบเขตขีดจำกัด

PHP หยุดคำขอที่เกิน memory_limit โดยขัดจังหวะผ่าน longjmp() การขัดจังหวะจึงเกิดขึ้นกลางการทำงานภายในได้ ขณะที่ข้อมูลของคำขอยังถูกกำหนดค่าเริ่มต้นเพียงบางส่วน เช่นระหว่างการแยกวิเคราะห์การอัปโหลดไฟล์ในฟอร์ม

จากนั้นการทำความสะอาดคำขออาจถือว่าข้อมูลที่ไม่ถูกต้องเป็นข้อมูลที่ใช้ได้ และคืนหน่วยความจำที่ไม่เคยถูกกำหนดค่าเริ่มต้น หน่วยความจำนั้นอาจยังมีข้อมูลจากการจัดสรรครั้งก่อนที่ผู้โจมตีควบคุมอยู่ ผลลัพธ์คือความเสียหายของหน่วยความจำซึ่งอาจนำไปสู่การรันโค้ด

CVE-2026-109619 – สถานะโกลบอลที่ตกค้าง

สถานะภายในที่เป็นของคำขอหนึ่งอาจอยู่ต่อหลังจากหน่วยความจำถูกคืนแล้ว เช่นหลังเกิดข้อผิดพลาดร้ายแรง คำขอถัดไปที่ทำงานในโปรเซสเวิร์กเกอร์เดียวกันอาจใช้สถานะที่ตกค้างนั้นก่อนที่การกำหนดค่าเริ่มต้นปกติจะรีเซ็ตทัน

ดังนั้นทั้งสองช่องโหว่จึงไม่ต้องอาศัยบั๊กในแอปพลิเคชันของคุณเลย แต่อยู่ในกลไกจัดการคำขอของ PHP เอง

exploit ที่สาธิตให้เห็นแสดงว่าคำขอเดียวที่ไม่ต้องยืนยันตัวตนสามารถกระตุ้นการโจมตีได้ก่อนที่โค้ดแอปพลิเคชันจะทำงานแม้แต่บรรทัดเดียว

ใครได้รับผลกระทบ

ทุกการติดตั้ง PHP ที่ให้บริการทราฟฟิกเว็บ ทีม PHP มองว่า mod_php เป็นการตั้งค่าที่เสี่ยงที่สุด

  • PHP 8.5 ก่อน 8.5.12
  • PHP 8.4 ก่อน 8.4.27
  • PHP 8.3 ก่อน 8.3.36
  • PHP 8.2 ก่อน 8.2.35
  • สาขาที่หมดอายุการสนับสนุน (PHP 8.1 และเก่ากว่า) ซึ่งไม่ได้รับการอัปเดตตามปกติแล้ว

นอกจากนี้ ผลิตภัณฑ์เชิงพาณิชย์และโอเพนซอร์สจำนวนมากใช้ PHP อยู่เบื้องหลัง จึงอาจได้รับผลกระทบแม้คุณไม่ได้ดูแลการติดตั้ง PHP เอง NCSC-NL ได้เผยแพร่รายการซอฟต์แวร์บุคคลที่สามที่มี PHP ฝังอยู่

ข้อผิดพลาดที่พบบ่อยที่สุด: นับเฉพาะเซิร์ฟเวอร์ที่คุณติดตั้งเอง อย่าลืมคอนเทนเนอร์ อิมเมจ CI อุปกรณ์ เครื่องมือภายใน และบริการที่ผู้ให้บริการดูแลให้

ตรวจสอบสถานะ – ห้านาทีต่อสภาพแวดล้อม

  1. รัน php -v บนทุกโฮสต์และในทุกคอนเทนเนอร์ ไม่ใช่แค่เครื่องเดียว
  2. ทำบัญชีสภาพแวดล้อมรันไทม์: พูล PHP-FPM, Apache กับ mod_php, php-cgi, FrankenPHP, LiteSpeed
  3. สร้างอิมเมจคอนเทนเนอร์ใหม่ – สิ่งที่นับคืออิมเมจฐาน ไม่ใช่อินสแตนซ์ที่กำลังรัน
  4. ถามผู้ให้บริการที่ดูแลผลิตภัณฑ์ที่พึ่งพา PHP ให้คุณ: รันเวอร์ชันใดอยู่ และจะแก้ไขเมื่อไร
  5. หาสาขาที่หมดอายุการสนับสนุน PHP 8.1 และเก่ากว่าไม่ได้รับแพตช์ตามปกติแล้ว

แก้ไข

แพ็กเกจของดิสทริบิวชัน ดิสทริบิวชันลินุกซ์และผู้ให้บริการ LTS มีแพตช์ล่วงหน้าแล้ว อัปเดตผ่านตัวจัดการแพ็กเกจและรีสตาร์ตโปรเซสเวิร์กเกอร์

คอนเทนเนอร์ อัปเดตอิมเมจฐานและสร้างใหม่ การรีสตาร์ตอิมเมจเก่าไม่ได้แก้อะไร

คอมไพล์เอง อัปเกรดเป็น 8.5.12, 8.4.27, 8.3.36 หรือ 8.2.35

เวอร์ชันที่หมดอายุการสนับสนุน ทีม PHP เผยแพร่ backport ขั้นต่ำสำหรับ 7.4, 8.0 และ 8.1 สำหรับผู้ที่คอมไพล์จากซอร์สหรือไม่มีผู้ให้บริการ LTS หากมีผู้ให้บริการ LTS ให้ติดต่อก่อน

rpms.remirepo.net: รีโพซิทอรีที่ดูแลโดยอาสาสมัครนี้ไม่ได้รับการอัปเดตในวันเผยแพร่ ทีม PHP แนะนำให้ย้ายไปใช้แพ็กเกจของดิสทริบิวชันหรือคอมไพล์จากซอร์ส

หลังอัปเดต ให้รีสตาร์ต PHP-FPM และโปรเซสเวิร์กเกอร์อื่น ๆ ไบนารีใหม่ที่ไม่ได้รีสตาร์ตก็ยังเป็นโปรเซสเก่าอยู่ดี

หากวันนี้ยังแพตช์ไม่ได้

มาตรการด้านล่างลดการเปิดรับเส้นทางการโจมตีบางเส้นทาง แต่ไม่ได้ทำให้การติดตั้งปลอดภัย มีเพียงการอัปเดตเท่านั้นที่ปิดช่องโหว่

สำหรับ CVE-2026-109618:

  • ตั้ง memory_limit=-1 ในลักษณะที่แอปพลิเคชันเขียนทับไม่ได้ เช่น php_admin_value ในพูล FPM หรือในการตั้งค่า Apache ตรวจสอบว่าไม่มีพูล ไดเรกทอรี หรือการตั้งค่าแอปใดที่ตั้งขีดจำกัดกลับมา
  • ตั้ง post_max_size ให้ต่ำ: 8M สำหรับแอปที่ไม่มีการอัปโหลดไฟล์, 32M ในที่ที่จำเป็นต้องอัปโหลด และให้ upload_max_filesize ต่ำกว่า post_max_size
  • ตั้งขีดจำกัดที่เว็บเซิร์ฟเวอร์หรือพร็อกซีสำหรับขนาดคำขอหลังถอดรหัส จำนวนฟิลด์ จำนวนส่วน multipart จำนวนเฮดเดอร์ และความลึกของการซ้อน ขีดจำกัดต้องครอบคลุมคำขอที่ไม่มี Content-Length ที่ใช้ได้ด้วย
  • ใช้ขีดจำกัดหน่วยความจำของคอนเทนเนอร์หรือ cgroup เป็นขีดจำกัดด้านความพร้อมใช้งาน และควรใช้นโยบายที่ฆ่าเฉพาะโปรเซสเวิร์กเกอร์ที่ได้รับผลกระทบ อย่าใช้ RLIMIT_AS หรือ RLIMIT_DATA เพราะอาจกระตุ้นเส้นทางการจัดสรรที่เปราะบาง

สำหรับ CVE-2026-109619:

  • ตั้ง session.upload_progress.enabled=0 และรีสตาร์ตทุกโปรเซสเวิร์กเกอร์ ตั้งใน php.ini ในพูล FPM หรือในการตั้งค่าเซิร์ฟเวอร์ เพื่อให้มีผลก่อนการแยกวิเคราะห์คำขอ อย่าพึ่ง ini_set() หรือ .user.ini ของ FPM
  • บน PHP 8.5: ตั้ง fatal_error_backtraces=0 และรีสตาร์ตทุกโปรเซสเวิร์กเกอร์
  • ลบการตั้งค่าระดับคำขอที่ไม่ถูกต้องหรือล้าสมัยซึ่งส่งข้อมูลวินิจฉัยก่อนการกำหนดค่าเริ่มต้น การซ่อนข้อมูลวินิจฉัยด้วย error_reporting, display_errors หรือ @ ไม่ช่วย
  • แก้ไขข้อผิดพลาดร้ายแรงและขีดจำกัดเวลาทำงานที่ผู้โจมตีเข้าถึงได้ เช่นใน callback การอัปโหลด การนำเข้า และการทำความสะอาด

ทำไมไม่ควรรอ

สามสิ่งทำให้เหตุการณ์นี้ต่างจากการแพตช์ทั่วไป:

  1. ไม่ต้องยืนยันตัวตน ไม่มีการล็อกอินให้ซ่อนอยู่ข้างหลัง
  2. การโจมตีเกิดก่อนโค้ดของคุณ ตรรกะแอปพลิเคชัน กฎ WAF และโมเดลสิทธิ์ไม่ได้เป็นเกราะกั้นในที่นี้
  3. PoC ออกมาแล้ว สิ่งที่ปกติใช้เวลาหลายสัปดาห์ มีคนทำเสร็จแล้ว

ต้นทุนของการแพตช์และรีสตาร์ตวันนี้เล็กน้อยมากเมื่อเทียบกับต้นทุนของการถูกบุกรุก โดยเฉพาะหากคุณอยู่ในขอบเขต NIS2 ซึ่งเหตุการณ์สำคัญต้องรายงานภายใน 24 ชั่วโมง

หลังแพตช์ – สามสิ่ง

  1. ตรวจสอบบนทุกโหนด ดูเวอร์ชัน ไม่ใช่แค่ตัวจัดการแพ็กเกจตอบ OK
  2. อ่านล็อกย้อนหลัง คำขอ POST แบบ multipart, การตอบกลับ 500 ที่ไม่คาดคิด, โปรเซสเวิร์กเกอร์ที่ล่ม และทราฟฟิกจากแหล่งที่ไม่รู้จักในหลายวันที่ผ่านมา
  3. หากสงสัยแม้เล็กน้อย: เริ่มขั้นตอนตอบสนองเหตุการณ์ ตัดการเชื่อมต่อ รักษาล็อก และประเมินหน้าที่ในการรายงาน

แหล่งอ้างอิง

  • CERT-EU, Security Advisory 2026-018: https://cert.europa.eu/publications/security-advisories/2026-018/
  • PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35: https://www.php.net/
  • GHSA-w8hw-w9fx-j79w: https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
  • GHSA-6wmf-4rv5-p3rp: https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
  • NCSC-NL, รายการผลิตภัณฑ์ที่มี PHP ฝังอยู่: https://github.com/NCSC-NL/php2shell

ช่องโหว่แบบนี้คือเหตุผลของความปลอดภัยต่อเนื่องด้วยตัวมันเอง: การแพตช์ การตรวจสอบ และการเฝ้าระวังที่ทำงานตลอดเวลา ไม่ใช่การทบทวนปีละครั้ง อ่านเพิ่มเติมว่าความปลอดภัยต่อเนื่องหมายถึงอะไรในทางปฏิบัติ

ต้องการทราบว่าคุณอยู่จุดไหน?

การสนทนา 30 นาทีโดยไม่มีค่าใช้จ่ายให้ภาพที่ตรงไปตรงมาของความเสี่ยงของคุณ

พูดคุยกับที่ปรึกษา