สรุปสั้น

ทีมพัฒนาภาษา Ruby ออกเวอร์ชัน 4.0.9, 3.4.12 และ 3.3.13 เมื่อวันที่ 23 ตุลาคม 2569 เพื่อแก้บั๊ก 3 ตัวใน Onigmo ซึ่งเป็นเอนจิน regular expression ที่ฝังอยู่ในตัวภาษา บั๊กชุดนี้คือต้นเหตุของช่องโหว่ระดับวิกฤต 4 ตัวที่บริษัท GitLab แพตช์ไปตลอดเดือนที่ผ่านมา รวมถึง CVE-2026-97229 และ CVE-2026-110264 คะแนน CVSS 10.0 ที่เปิดให้รันโค้ดได้โดยไม่ต้องล็อกอิน GitLab พบว่า pattern ที่สร้างขึ้นเป็นพิเศษทำให้หน่วยความจำเสียหายระหว่างที่ Ruby คอมไพล์ regex และอาจนำไปสู่การรันโค้ดบนเซิร์ฟเวอร์ แต่ Ruby ยืนยันว่าปัญหาไม่ได้จำกัดอยู่ที่ GitLab แอปพลิเคชันใดก็ตามที่สร้าง regex จากข้อความที่ผู้โจมตีควบคุมได้อยู่ในข่ายเสี่ยงทั้งหมด

ผู้ใช้ Ruby 4.0 ต้องติดตั้ง 4.0.9 เพราะ 4.0.8 ที่ออกในสัปดาห์เดียวกันยังไม่มีแพตช์ของ CVE-2026-110264 ส่วน Ruby 3.2 ลงไปจะไม่ได้รับแพตช์เพราะหมดอายุซัพพอร์ตแล้ว มาตรการที่ดูเหมือนช่วยได้อย่าง Regexp.timeout หรือการจำกัดความยาว pattern ก็ใช้ไม่ได้ผล และจุดที่ผู้ดูแลต้องระวังเป็นพิเศษคือ Ruby ยังไม่ขอหมายเลข CVE ของตัวเอง ระเบียน CVE ที่มีอยู่จึงระบุเฉพาะ GitLab เป็นผลิตภัณฑ์ที่ได้รับผลกระทบ สแกนเนอร์ที่เทียบเวอร์ชัน Ruby กับฐานข้อมูล CVE จึงอาจไม่แจ้งเตือนอะไรเลย

รายละเอียดข่าว

เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 23 ตุลาคม 2569 ว่า Ruby ออกประกาศแยกเพื่ออธิบายการแก้ไข regex ที่เกี่ยวข้องกับ CVE ของ GitLab โดยแพตช์ทั้งสามตัวอยู่ในเวอร์ชัน 4.0.9, 3.4.12 และ 3.3.13 ซึ่ง 3.4.12 และ 3.3.13 เป็นรุ่นแรกในสายของตัวเองที่มีแพตช์ชุดนี้ ส่วนสาย 4.0 นั้น 4.0.8 ที่ออกก่อนหน้าในสัปดาห์เดียวกันมีแพตช์ไม่ครบ ขาดตัวที่แก้ CVE-2026-110264

GitLab เปิดให้ผู้ใช้ป้อน regular expression เองได้ในหลายจุด เช่น pattern ในไฟล์ตั้งค่า CI/CD และพบว่า pattern ที่ประดิษฐ์ขึ้นทำให้หน่วยความจำเสียหายตอน Ruby คอมไพล์ บริษัทออก CVE รวม 4 ตัวระหว่างวันที่ 23 กันยายนถึง 21 ตุลาคม 2569 และแก้แต่ละตัวด้วยการส่ง Ruby ที่แพตช์แล้วไปในแพ็กเกจของตัวเอง สองตัวแรกที่เปิดเผยวันที่ 23 กันยายนต้องมีบัญชีล็อกอินและได้คะแนน 9.9 ส่วนสองตัวในเดือนตุลาคม คือ CVE-2026-97229 เมื่อวันที่ 12 (2026/10/100 ) และ CVE-2026-110264 เมื่อวันที่ 21 (2026/10/231 ) ไม่ต้องล็อกอินและได้คะแนนเต็ม 10.0 โดยตัวหลังกระทบ GitLab ทุกเวอร์ชันตั้งแต่ 7.0

นักวิจัยผู้ใช้ชื่อ joaxcar เป็นผู้รายงานทั้ง 4 ตัวผ่านโครงการ bug bounty ของ GitLab และ ณ วันที่ 23 ตุลาคม 2569 ยังไม่มีตัวใดอยู่ในแคตตาล็อก Known Exploited Vulnerabilities (KEV) ของ CISA

รายละเอียดช่องโหว่

ตามประกาศของ Ruby แอปพลิเคชันจะได้รับผลกระทบก็ต่อเมื่อคอมไพล์ regular expression จากสตริงที่ผู้โจมตีควบคุมได้เท่านั้น ซึ่งเกิดขึ้นเมื่อโปรแกรมส่งสตริงนั้นเข้า Regexp.new, Regexp.union หรือ Regexp.compile หรือแทรกสตริงลงใน pattern ผ่าน interpolation เช่น /#{input}/ แอปที่ใช้เฉพาะ regex ที่นักพัฒนาเขียนไว้เองไม่ได้รับผลกระทบ เพราะผู้โจมตีส่ง pattern เข้าไปให้ตัวคอมไพล์ไม่ได้

บั๊กทั้ง 3 ตัวอยู่ในขั้นคอมไพล์ pattern ไม่ใช่ขั้นจับคู่ข้อความ นี่คือเหตุผลที่ Ruby ระบุว่า Regexp.timeout ไม่ช่วย เพราะ timeout ควบคุมเวลาจับคู่ ไม่ได้ควบคุมการคอมไพล์ ส่วนการจำกัดความยาว pattern ก็เชื่อถือไม่ได้ เพราะ pattern สั้น ๆ ก็ทำให้เกิดบั๊กได้ ทางเดียวสำหรับผู้ที่ยังอัปเกรดไม่ได้คือหยุดคอมไพล์ regex จากอินพุตที่ไม่น่าเชื่อถือ

อีกประเด็นคือสถานะ CVE Ruby ระบุว่ายังไม่ขอหมายเลข CVE ของตัวเอง “อย่างน้อยในตอนนี้” และให้ผู้ใช้ติดตามปัญหาผ่านหมายเลข CVE ทั้ง 4 ตัวของ GitLab แทน ทั้งที่ในอดีต Ruby เคยออก CVE ให้บั๊กประเภทเดียวกันในตัวคอมไพล์ regex มาแล้ว คือ CVE-2022-28738 (double free) ในปี 2565 และ CVE-2024-27282 (อ่านหน่วยความจำได้ตามใจ) ในปี 2567 ขณะที่เอกสารของ Ruby ยังอธิบายความเสี่ยงของ pattern ที่ไม่น่าเชื่อถือไว้เพียงว่าเป็นความเสี่ยงด้าน denial-of-service เท่านั้น Ruby ระบุว่าจะอัปเดตประกาศหากขอ CVE ในภายหลัง

ผลกระทบ

GitLab แบบ self-managed ที่อัปเดตตามแพตช์ 21 ตุลาคมแล้วถือว่าปลอดภัยจากบั๊กชุดนี้ เพราะ GitLab ฝัง Ruby ที่แพตช์แล้วมาในแพ็กเกจเอง กลุ่มที่น่าห่วงกว่าคือแอปพลิเคชัน Ruby และ Rails อื่นที่มีฟีเจอร์ให้ผู้ใช้ป้อน regex เอง เช่น ระบบค้นหาขั้นสูง ระบบกรองล็อก กฎ routing หรือเครื่องมือ DevOps ที่ให้กำหนด pattern ได้ แอปเหล่านี้ไม่ได้อยู่ในประกาศของ GitLab และอาจไม่รู้ตัวว่ามีพื้นผิวการโจมตีแบบเดียวกัน

ช่องว่างเรื่อง CVE ทำให้ความเสี่ยงนี้มองเห็นยากขึ้นอีก ระบบจัดการช่องโหว่ส่วนใหญ่ทำงานโดยเทียบเวอร์ชันซอฟต์แวร์ที่ติดตั้งกับระเบียน CVE เมื่อระเบียนทั้ง 4 ตัวระบุเฉพาะ GitLab เซิร์ฟเวอร์ที่รัน Ruby 3.3 หรือ 3.4 เวอร์ชันเก่าจึงอาจผ่านการสแกนโดยไม่มีการแจ้งเตือน ส่วนระบบที่ยังรัน Ruby 3.2 หรือเก่ากว่าจะไม่มีแพตช์ให้เลย และต้องพึ่งการแก้โค้ดหรือการอัปเกรดสายหลักเท่านั้น

คำแนะนำ

  • อัปเกรด Ruby เป็น 4.0.9, 3.4.12 หรือ 3.3.13 ตามสายที่ใช้ ผู้ใช้สาย 4.0 อย่าหยุดที่ 4.0.8 เพราะยังขาดแพตช์ CVE-2026-110264
  • ระบบที่ยังใช้ Ruby 3.2 หรือเก่ากว่า วางแผนย้ายไปสาย 3.4 หรือ 4.0 ตามคำแนะนำของ Ruby เพราะจะไม่มีแพตช์ย้อนหลัง
  • ค้นหาในซอร์สโค้ดว่ามีการเรียก Regexp.new, Regexp.union, Regexp.compile หรือ interpolation แบบ /#{...}/ กับข้อมูลจากผู้ใช้หรือไม่ หากมีและยังอัปเกรดไม่ได้ ให้ปิดฟีเจอร์นั้นชั่วคราวหรือเปลี่ยนเป็นการจับคู่สตริงแบบไม่ใช้ regex
  • อย่าพึ่ง Regexp.timeout หรือการจำกัดความยาว pattern เป็นมาตรการป้องกันบั๊กชุดนี้
  • ตรวจ inventory เวอร์ชัน Ruby บนเซิร์ฟเวอร์และ container image ด้วยตัวเอง อย่ารอผลจากสแกนเนอร์ที่อิงระเบียน CVE เพียงอย่างเดียว
  • ผู้ดูแล GitLab self-managed ยืนยันว่าอัปเดตเป็น 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 หรือ 18.11.13 แล้ว และใช้กฎตรวจจับที่ GitLab เผยแพร่ค้นหาความพยายามโจมตีย้อนหลัง

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