2 คะแนน โดย GN⁺ 2025-12-30 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • MongoBleed (CVE-2025-14847) เป็นช่องโหว่การรั่วไหลของหน่วยความจำร้ายแรงที่มีอยู่ใน MongoDB ทุกเวอร์ชัน ตั้งแต่ปี 2017 ทำให้ผู้โจมตีสามารถอ่าน ข้อมูลใด ๆ ใน heap memory ของฐานข้อมูล ได้
  • ช่องโหว่นี้เกิดจาก บั๊กในเส้นทางการบีบอัด zlib และสามารถถูกใช้โจมตีได้เพียงแค่เชื่อมต่อกับฐานข้อมูล โดยไม่ต้องยืนยันตัวตน
  • ผู้โจมตีสามารถส่ง คำขอแบบบีบอัดที่ถูกดัดแปลง เพื่อหลอกให้เซิร์ฟเวอร์จัดสรรบัฟเฟอร์ผิดขนาด และเปิดเผย หน่วยความจำจากงานก่อนหน้า (เช่น รหัสผ่าน, API key) ที่อยู่ภายในได้
  • MongoDB ปล่อยแพตช์เมื่อวันที่ 19 ธันวาคม 2025 แต่ เวอร์ชัน EOL (3.6, 4.0, 4.2) ไม่ได้รับการแก้ไข
  • ช่องโหว่นี้มีอยู่มานาน 8 ปีและส่งผลต่อ อินสแตนซ์ MongoDB ที่เปิดเผยบนอินเทอร์เน็ตมากกว่า 210,000 ตัว จึงจำเป็นต้อง อัปเดตแพตช์ทันทีหรือปิดการบีบอัด ทั้งในสภาพแวดล้อมคลาวด์และออนพรีเมส

ภาพรวมของ MongoBleed

  • MongoBleed (CVE-2025-14847) เป็นช่องโหว่ที่พบใน เส้นทางการบีบอัดข้อความ zlib 1 ของ MongoDB และส่งผลกระทบต่อทุกเวอร์ชันตั้งแต่ปี 2017
    • ผู้โจมตีเพียงแค่เชื่อมต่อกับฐานข้อมูลโดยไม่ต้องยืนยันตัวตน ก็สามารถอ่าน ข้อมูลใด ๆ ใน heap memory ได้
    • เวอร์ชันที่ หมดระยะซัพพอร์ต (EOL) เช่น MongoDB 3.6, 4.0, 4.2 จะไม่ได้รับการแก้ไข
  • บั๊กนี้ถูกนำเข้ามาจาก PR เมื่อเดือนพฤษภาคม 2017 และถูกเปิดเผยอย่างเป็นทางการในวันที่ 19 ธันวาคม 2025
  • MongoDB ระบุว่าได้ใช้แพตช์กับทุกอินสแตนซ์แล้ว รวมถึง บริการคลาวด์ Atlas

โครงสร้างการสื่อสารของ MongoDB

  • MongoDB ใช้ โปรโตคอล TCP ของตนเองแทน HTTP และส่งข้อความในรูปแบบ BSON (Binary JSON)
  • คำขอทั้งหมดประกอบด้วยคำสั่ง OP_MSG และเมื่อมีการบีบอัดจะถูกห่อด้วยข้อความ OP_COMPRESSED
    • ภายในข้อความมีฟิลด์อย่าง uncompressedSize, originalOpcode, compressorId
    • uncompressedSize หมายถึงขนาดที่คาดไว้หลังการคลายการบีบอัด

ขั้นตอน exploit ที่ 1 — การจัดสรรบัฟเฟอร์ผิดพลาด

  • ผู้โจมตีตั้งค่า uncompressedSize ให้เป็น ค่าที่ใหญ่เกินจริง เพื่อให้เซิร์ฟเวอร์จัดสรรบัฟเฟอร์ขนาดใหญ่
    • ตัวอย่าง: ประกาศข้อความจริงขนาด 1KB ให้เป็น 1MB
  • เซิร์ฟเวอร์ MongoDB หลังคลายการบีบอัดแล้วจะ ไม่ตรวจสอบขนาดจริง แต่เชื่อค่าที่ผู้ใช้ระบุ
    • ส่งผลให้หน่วยความจำคงอยู่ในรูปแบบ [ข้อมูลจริง | heap garbage ที่ไม่ได้อ้างอิง]
  • MongoDB ที่พัฒนาด้วย C++ ไม่มีการ initialize หน่วยความจำในส่วนนี้ จึงอาจมี ข้อมูลอ่อนไหวจากงานก่อนหน้า อยู่ภายใน
    • เช่น รหัสผ่าน, session token, API key, ข้อมูลลูกค้า, การตั้งค่าระบบ

ขั้นตอน exploit ที่ 2 — การรั่วไหลของข้อมูล

  • ผู้โจมตีส่ง อินพุต BSON ที่ไม่ถูกต้อง เพื่อชักนำให้เซิร์ฟเวอร์ parse ข้อมูลขยะในหน่วยความจำเป็นสตริง
    • ฟิลด์แรกของ BSON เป็นสตริง และเป็นไปตามกฎของ C ว่าด้วย สตริงแบบ null-terminated
  • หากผู้โจมตีส่ง สตริงที่ไม่มีอักขระจบ null เซิร์ฟเวอร์จะอ่านข้อมูลอื่นในหน่วยความจำต่อไปด้วย
    • ตัวอย่าง: [ { "a | password: 123\0 | apiKey: jA2sa | ip: 219.117.127.202 ]
  • จากนั้นเซิร์ฟเวอร์จะมองว่านี่เป็นฟิลด์ BSON ที่ไม่ถูกต้อง และตอบกลับพร้อมข้อความผิดพลาดที่มีเนื้อหาดังกล่าว
    • "errmsg": "invalid BSON field name 'a | password: 123'"
  • เมื่อทำซ้ำกระบวนการนี้ ผู้โจมตีสามารถ สแกน heap memory ทั้งหมด และรวบรวมข้อมูลอ่อนไหวได้

ผลกระทบและความเสี่ยง

  • ช่องโหว่นี้เกิดขึ้นในขั้นตอน ก่อนการยืนยันตัวตน (pre-auth) ทำให้ผู้โจมตีเข้าถึงข้อมูลได้โดยไม่ต้องล็อกอิน
  • อินสแตนซ์ MongoDB ที่เปิดเผยบนอินเทอร์เน็ต จึงตกอยู่ในความเสี่ยงทันที
    • จากการค้นหาผ่าน Shodan พบอินสแตนซ์ MongoDB ที่เปิดเผยมากกว่า 213,000 ตัว
  • ช่องโหว่นี้มีอยู่ตั้งแต่ ปี 2017 ถึง 2025 รวมราว 8 ปี และด้วยโครงสร้างที่เรียบง่ายจึงมีโอกาสถูกใช้โจมตีจริงสูง
  • MongoDB ระบุว่า “ยังไม่มีหลักฐานการถูกใช้โจมตีจนถึงตอนนี้” แต่ ไม่ได้เผยคำขอโทษอย่างเป็นทางการหรือไทม์ไลน์โดยละเอียด

วิธีบรรเทา

  • อัปเดตเป็น เวอร์ชันที่มีแพตช์ล่าสุด (8.0.17 ขึ้นไป)
  • ในระยะสั้นสามารถบรรเทาได้ด้วยการ ปิดการบีบอัดเครือข่าย zlib
  • ผู้ใช้ MongoDB Atlas ได้รับแพตช์เรียบร้อยแล้ว

ข้อมูลเพิ่มเติมและประเด็นที่เกี่ยวข้อง

  • หัวหน้าทีมความปลอดภัยของ Elastic ตั้งชื่อช่องโหว่นี้ว่า ‘MongoBleed’ และเผยแพร่ PoC (สคริปต์ Python)
    • MongoDB และ Elastic เป็นคู่แข่งกันในด้าน ฟังก์ชันการค้นหาและการวิเคราะห์
  • แหล่งข้อมูลที่เกี่ยวข้อง:

สรุป

  • MongoBleed คือ ช่องโหว่การรั่วไหลของหน่วยความจำ ที่เกิดจาก บั๊กในการจัดการการบีบอัด zlib
  • ผู้โจมตีสามารถใช้ คำขอแบบบีบอัดที่ถูกดัดแปลง เพื่อดึง ข้อมูลหน่วยความจำก่อนหน้า (เช่น รหัสผ่าน, API key) ออกมาได้
  • MongoDB ทุกเวอร์ชันในช่วงปี 2017–2025 ได้รับผลกระทบ และจำเป็นต้อง อัปเดตแพตช์หรือปิดการบีบอัด
  • อินสแตนซ์ที่เปิดเผยบนอินเทอร์เน็ตมากกว่า 210,000 ตัว อาจตกเป็นเป้าหมาย
  • แม้ MongoDB จะปล่อยแพตช์แล้ว แต่ก็มีข้อวิจารณ์เรื่อง ไม่รองรับเวอร์ชัน EOL และการเปิดเผยการตอบสนองล่าช้า

1 ความคิดเห็น

 
GN⁺ 2025-12-30
ความเห็นจาก Hacker News
  • หลายปีก่อนผมได้แก้ memory allocator ของรันไทม์ Cloudflare Workers ให้เขียนทับหน่วยความจำทั้งหมดด้วยรูปแบบไบต์คงที่ทุกครั้งที่มีการ free
    แบบนี้จะทำให้ไม่มีข้อมูลที่มีความหมายหลงเหลืออยู่ในหน่วยความจำที่ยังไม่ได้ initialize
    ตอนแรกคิดว่าน่าจะมีผลด้านประสิทธิภาพ แต่ในความเป็นจริงคือ ไม่มีผลที่วัดได้เลย
    ผมคิดว่าทุกคนที่ใช้ภาษาซึ่งไม่ปลอดภัยด้านหน่วยความจำควรทำแบบนี้ และบั๊กของ Mongo ครั้งนี้ก็น่าจะบรรเทาได้ด้วยวิธีนี้
    • macOS รุ่นใหม่จะทำ zero-out ให้อัตโนมัติเมื่อมีการ free หน่วยความจำ
      สิ่งนี้ช่วยให้การบีบอัดหน่วยความจำมีประสิทธิภาพขึ้น และโดยเฉลี่ยกลับทำให้ประสิทธิภาพดีขึ้นด้วยซ้ำ
    • บน FreeBSD ถ้าตั้งค่าตัวแปรสภาพแวดล้อม MALLOC_CONF=opt.junk=free malloc ก็จะทำงานแบบเดียวกัน
      กล่าวคือมี implementation จำนวนมากที่มีฟีเจอร์นี้ให้ใช้งานเป็นตัวเลือกอยู่แล้ว
    • ในปี 2025 ผมคิดว่า allocator ทั่วไปทั้งหมด ควร initialize หน่วยความจำเป็น 0 โดยค่าเริ่มต้น
      ถ้าต้องการประสิทธิภาพมากกว่านี้ก็เขียน custom allocator ให้เหมาะกับงานเฉพาะไปเลย
      และยังสามารถทำ optimization อย่างอื่นที่ system allocator ทำไม่ได้อีกด้วย
    • OpenBSD จะเติมหน่วยความจำที่เพิ่ง allocate ใหม่ด้วย 0xdb และหน่วยความจำที่ free แล้วด้วย 0xdf
      ทำให้จับบั๊กแบบ use-before-initialization หรือ use-after-free ได้อย่างรวดเร็ว
      และนี่เป็นค่าตั้งต้นอยู่แล้ว
    • สงสัยว่านี่ทำงานเหมือนกับการเปิดตัวเลือก init_on_free=1 ของเคอร์เนลหรือเปล่า
  • ดูเหมือนว่าผู้เขียนจะไม่ค่อยรู้กระบวนการพัฒนาภายในของ Mongo มากนัก
    Mongo พัฒนาใน private repository ภายในก่อน แล้วค่อยย้าย commit ไปยัง repository สาธารณะผ่าน Copybara
    ความสับสนเรื่องวันที่เกิดขึ้นจากกระบวนการนี้เอง
    • ผมก็ไม่รู้เหมือนกัน ก่อนหน้านี้รู้สึกแปลกที่ไม่มี PR review แต่ตอนนี้เข้าใจแล้ว
      กำลังจะอัปเดตบทความเพื่ออธิบายเรื่องนี้กับความต่างของวันที่
  • ดูเหมือนว่าผู้เขียนจะเข้าใจไทม์ไลน์ผิด
    Atlas cluster ของเราอัปเกรดเสร็จไปแล้วหลายวันก่อนมีการประกาศ CVE
    • ขอบคุณ อัปเดตบทความแล้ว
  • สำหรับระบบอย่างฐานข้อมูล การทำ zeroing หรือ poisoning ตอน free หน่วยความจำเป็นตัวเลือกที่ดี
    ทุกวันนี้ allocator ส่วนใหญ่ควรทำแบบนี้เป็นค่าเริ่มต้น
    Chris เคยปรับปรุงจุดนี้ใน Blink และผลลัพธ์ก็ขยายไปทั่วทั้ง Chromium
    เอกสารที่เกี่ยวข้องก็น่าสนใจเช่นกัน
    โพสต์บนบล็อก Chromium
    เอกสาร PartitionAlloc
  • สงสัยว่า Mongo instance ถูกเปิดออกสู่อินเทอร์เน็ตบ่อยแค่ไหน
    ฝั่ง SQL พบไม่บ่อยแต่ก็มีบ้างเป็นครั้งคราว
    • จากประสบการณ์ของผม เหตุผลที่ MongoDB มีอยู่คือ “ความขี้เกียจ”
      ปรัชญาคือไม่ต้องใส่ใจทั้ง schema, durability, การอ่าน/เขียน, การเชื่อมต่อ หรืออะไรเลย
      เพราะงั้นจะไม่ใส่ใจเรื่องความปลอดภัยด้วยก็ไม่น่าแปลก
    • องค์กรที่ “จริงจัง” 3 แห่งที่ผมรู้จัก ล้วนใช้ Mongo เพราะอยากหลีกเลี่ยงการออกแบบ schema
      ทัศนคติแบบนี้จะนำไปสู่แนวคิดว่า “ขอให้สะดวกตอนนี้ก่อน” และสุดท้ายก็โยงไปถึงปัญหาความปลอดภัยอย่าง DB instance ที่เปิดสาธารณะ
    • ความเห็นพวกนี้ดูสุดโต่งเกินไปหน่อย
      ในความเป็นจริงการใช้ SQL กับ NoSQL ร่วมกัน เป็นเรื่องปกติ
      NoSQL เด่นเรื่องความพร้อมใช้งานสูงสำหรับข้อมูลขนาดใหญ่ ส่วน SQL เหมาะกับการเก็บข้อมูลเชิงสัมพันธ์
      เช่น iMessage หรือระบบ matchmaking ของ EA ก็ใช้ NoSQL
      สุดท้ายแล้วทั้งคู่จำเป็น ไม่ใช่คู่แข่งกันแต่เป็น ความสัมพันธ์แบบเสริมกัน
    • ตาม ผลการค้นหาบน Shodan มี Mongo instance ที่เปิดเผยอยู่ 213,000 ตัว
    • ถ้าเปิด SQL server ออกสู่ภายนอก ผลลัพธ์จะร้ายแรงกว่าอีก
      เช่น PostgreSQL สามารถมีสิทธิ์ระดับทั้งระบบได้แม้เป็นการตั้งค่าพื้นฐาน
      เพราะแบบนี้คนส่วนใหญ่จึงรู้ดีถึงความเสี่ยงของการเปิด SQL server สาธารณะ
  • MongoDB เคยประกาศเมื่อวันที่ 24 ธันวาคมว่า “ไม่มีหลักฐานว่ามีการ exploit CVE นี้” แต่ต้องไม่ลืมว่า “ไม่มีหลักฐาน ไม่ได้แปลว่าเป็นหลักฐานว่าไม่มี”
    • ถ้าอย่างนั้นคุณคิดว่าพวกเขาควรพูดว่าอะไร?
  • ไม่เข้าใจว่าทำไมถึงยังใช้ Mongo กันอยู่
    • replication ทำได้ง่าย และเร็วกว่า JSONB ของ Postgres
      ส่วนตัวผมไม่อยากใช้ แต่ก็มีกรณีที่ DynamoDB หรือ MongoDB เหมาะสมในเชิงเทคนิคจริง ๆ
    • ก็มีมุกที่บอกว่าใช้เพราะ “web scale”
      วิดีโอที่เกี่ยวข้อง
    • เมื่อก่อน NoSQL เคยเป็นกระแส แต่สุดท้ายก็ลงเอยเป็นแค่ key-value DB แบบเรียบง่าย
    • ตรรกะแบบนี้ก้าวร้าวเกินไปเลยรับได้ยาก
  • ทำให้นึกถึง มุมมองเชิงบวกเกินจริง ที่ว่า OWASP Top 10 จะช่วยแก้ช่องโหว่หลัก ๆ ได้
    แต่ buffer overflow ก็ยังคงมีอยู่มาตั้งแต่ปี 2003
    • สุดท้ายก็เหมือนเอา footgun ไปแจกให้ทุกคน
      ปัญหาแบบนี้จะเกิดซ้ำไปเรื่อย ๆ ตราบใดที่ไม่ได้ป้องกันในระดับภาษา
      ขอส่งกำลังใจให้ทีมพัฒนา Mongo
  • ทุกครั้งที่มีบทความเกี่ยวกับ NoSQL ขึ้นมา ก็จะเห็นชัดว่ามี “นักพัฒนา” จำนวนมากที่ ไม่เคยรับมือกับทราฟฟิกขนาดใหญ่จริง ๆ
    • ครั้งนี้ดูเหมือนจะเป็นคุณคนเดียวมากกว่านะ
  • MongoDB แย่มาตลอด... แต่ก็ถูกเรียกว่า “webscale”
    ผมว่าหันไปใช้ ToroDB หรือ JSONB ของ PostgreSQL จะดีกว่า