1 คะแนน โดย GN⁺ 2023-09-13 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • มีการปล่อยอัปเดต Chrome ช่อง Stable และ Extended Stable บนเดสก์ท็อป ซึ่งรวมการแก้ไขช่องโหว่ WebP heap buffer overflow
  • บิลด์ใหม่คือ 116.0.5845.187 บน Mac และ Linux และ 116.0.5845.187/.188 บน Windows โดยจะทยอยปล่อยภายในช่วงตั้งแต่ไม่กี่วันถึงหลายสัปดาห์
  • การแก้ไขด้านความปลอดภัยในรีลีสนี้มี 1 รายการ และ CVE-2023-4863 ถูกจัดเป็นระดับ Critical
  • Apple SEAR และ The Citizen Lab แห่ง Munk School, University of Toronto รายงานช่องโหว่นี้เมื่อวันที่ 6 กันยายน 2023
  • Google ระบุว่ามี กรณีการนำไปใช้โจมตีจริง และการเข้าถึงรายละเอียดบั๊กอาจถูกจำกัดจนกว่าจะติดตั้งเวอร์ชันที่แก้ไขแล้ว

อัปเดตช่อง Chrome บนเดสก์ท็อป

  • ช่อง Stable และ Extended Stable ได้รับการอัปเดตเป็นบิลด์ใหม่สำหรับเดสก์ท็อป
  • เวอร์ชันของช่อง Stable แยกตามแพลตฟอร์มมีดังนี้
    • Mac: 116.0.5845.187
    • Linux: 116.0.5845.187
    • Windows: 116.0.5845.187/.188
  • ช่อง Extended Stable ก็ถูกปล่อยเป็นเวอร์ชันแยกเช่นกัน
    • Windows: 116.0.5845.188
    • Mac: 116.0.5845.187
  • อัปเดตจะทยอยปล่อย ภายในไม่กี่วันถึงหลายสัปดาห์
  • ดูรายการการเปลี่ยนแปลงทั้งหมดของบิลด์นี้ได้ที่ log

การแก้ไขด้านความปลอดภัย: CVE-2023-4863

  • รีลีสนี้มี การแก้ไขด้านความปลอดภัย 1 รายการ
  • การแก้ไขสำคัญที่มีผู้วิจัยภายนอกมีส่วนร่วมคือช่องโหว่ต่อไปนี้
    • Critical CVE-2023-4863: heap buffer overflow ใน WebP
    • หมายเลขบั๊ก: 1479274
    • ผู้รายงาน: Apple Security Engineering and Architecture(SEAR), The Citizen Lab แห่ง Munk School, University of Toronto
    • วันที่รายงาน: 6 กันยายน 2023
    • มูลค่ารางวัล: $NA

การโจมตีที่เกิดขึ้นจริงและข้อจำกัดการเปิดเผยข้อมูล

  • Google ระบุว่ามี exploit ของ CVE-2023-4863 อยู่ในสภาพแวดล้อมจริง
  • การเข้าถึงรายละเอียดบั๊กและลิงก์ที่เกี่ยวข้องอาจถูกจำกัดจนกว่าผู้ใช้ส่วนใหญ่จะอัปเดตเป็นเวอร์ชันที่แก้ไขแล้ว
  • ข้อจำกัดนี้อาจยังคงอยู่ หากบั๊กเดียวกันนั้นอยู่ใน ไลบรารีของบุคคลที่สาม ที่โปรเจกต์อื่นพึ่งพาและยังไม่ได้รับการแก้ไข

ช่องทางตรวจพบและรายงานบั๊กความปลอดภัย

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

 
GN⁺ 2023-09-13
ความคิดเห็นจาก Hacker News
  • ใน Google Chrome รูปภาพ WebP จะถูกถอดรหัสใน โปรเซสเรนเดอร์เรอร์ ดังนั้นแม้ exploit จะสำเร็จ ก็ทำได้เพียงรันโค้ดของเรนเดอร์เรอร์ภายใน sandbox เท่านั้น
    เรนเดอร์เรอร์มีความซับซ้อนมาก จึงพบ exploit จำนวนมากทุกปี แต่ถึงจะได้สิทธิ์รันโค้ดในเรนเดอร์เรอร์ ก็แทบไม่เกินสิทธิ์ที่เว็บเพจทั่วไปมีอยู่
    โดยเฉพาะอย่างยิ่ง ไม่สามารถดูหรือทิ้งไฟล์ไว้ในไฟล์ซิสเต็มภายในเครื่องได้ และไม่สามารถอ่านคุกกี้ของโดเมนอื่นได้ด้วย

    • แน่นอนว่าถ้ามี exploit สำหรับหลุด sandbox มาผนวกด้วย เรื่องก็จะเปลี่ยนไป
      ไม่ได้เป็นเรื่องที่ต้องให้ความสำคัญสูงสุดทันที แต่ถ้า exploit แบบนั้นไม่ได้กำลังแพร่ระบาดอยู่จริง ก็ควรแพตช์ให้เร็วที่สุดเท่าที่ทำได้ในช่วงเวลาที่ไม่ทำให้ลำบากมากนัก
    • อินเทอร์เน็ตยุคใหม่มีรูปภาพที่ผู้ใช้อัปโหลดจำนวนมหาศาล ดังนั้นแค่ได้สิทธิ์ในบริบทผู้ใช้ของเว็บไซต์เดียวก็ถือว่าใหญ่มากแล้ว
      ในแง่ที่ไม่ได้ผูกติดกับไซต์หรือฟรอนต์เอนด์ใดไซต์หนึ่ง มันใกล้เคียงกับ XSS เวอร์ชันเสริมพลัง
    • ผมใช้ WebP แบบ lossless อยู่ ซึ่งมีประสิทธิภาพดีกว่า PNG มาก
      อ้อ ผมตอบผิดเธรด ตั้งใจจะตอบข้อความ “jpeg is good enough” ใน https://news.ycombinator.com/item?id=37479576
    • หมายความว่าเรนเดอร์เรอร์ไม่สามารถส่งข้อมูลกลับไปยังเว็บไซต์ได้หรือเปล่า?
      แล้วถึงจะปิด JavaScript ไว้ อยู่ ๆ เว็บไซต์ก็ยังสามารถรันโค้ดได้อยู่ดีไม่ใช่หรือ?
  • เลยยิ่งเข้าใจมากขึ้นว่าทำไมนักพัฒนาเบราว์เซอร์ถึงช้าในการ นำฟอร์แมตใหม่มาใช้
    WebP ไม่ได้มีข้อได้เปรียบเหนือ JPEG มากนัก ส่วนใหญ่ก็แค่เรื่องความโปร่งใส และความสำเร็จก็ยังจำกัด
    แต่ตอนนี้กลับนำไปสู่ช่องโหว่ความปลอดภัยระดับความสำคัญสูงหลายรายการ และทุกที่ที่ลิงก์กับ libwebp คงต้องปล่อยแพตช์กันตลอดเดือนข้างหน้า
    ไม่ได้หมายความว่าไม่ควรทำของใหม่ แต่ผมคิดว่านักพัฒนามักประเมินต้นทุนต่ำไปค่อนข้างมาก

    • Firefox มีชั้น sandbox เพิ่มเติมที่สามารถใช้กับไลบรารีแต่ละตัวได้ ไม่ใช่เฉพาะทั้งโปรเซส: https://hacks.mozilla.org/2021/12/webassembly-and-back-again...
    • ถ้าพูดอย่างเป็นธรรม ในอดีตปัญหาของ ไลบรารีถอดรหัส JPEG ก็เคยถูกใช้เป็นช่องทางส่งมัลแวร์มาแล้ว
      จริงอยู่ที่ระบบนิเวศของ WebP ยังสุกงอมน้อยกว่ามาก แต่ผมมั่นใจว่าโค้ดที่จัดการฟอร์แมตเก่ากว่าก็มีปัญหาด้านความปลอดภัยอยู่ไม่น้อยเช่นกัน
      ถึงอย่างนั้นตรรกะนี้ก็สมเหตุสมผล แค่ไม่กี่สัปดาห์ก่อน ชาวเน็ตยังมีบรรยากาศว่าควรนำ JPEG XL มาใช้ให้เร็วที่สุด และเพื่อให้ทำเช่นนั้น นักพัฒนาเบราว์เซอร์ก็แค่ “ใส่โค้ด reference decoder เข้าไปใน codebase” ซึ่ง “แทบไม่มีต้นทุน”
    • ถ้าเบราว์เซอร์ไม่รับฟอร์แมตใหม่มาใช้ จะมีใครพบบั๊กแบบนี้ไหม?
      ฟอร์แมตรูปภาพและไลบรารีอื่น ๆ ก็น่าจะเต็มไปด้วยบั๊กเหมือนกัน แต่เพราะไม่ได้ถูกใช้ในซอฟต์แวร์หลัก ๆ จึงไม่มีใครสนใจ
      โดยเฉพาะสำหรับคนที่มีความสามารถในการค้นหาและใช้ประโยชน์จากบั๊กแบบนี้ ผลตอบแทนเทียบกับเวลาที่ใช้ไม่คุ้ม
      การไม่ได้ถูกใช้นาน ๆ ไม่ได้ทำให้บั๊กน้อยลง
    • สาเหตุของช่องโหว่ความปลอดภัยไม่ใช่ฟอร์แมตรูปภาพใหม่ แต่คือ การขาด memory safety ของ C/C++
      ถ้า image encoder และ decoder รวมถึง encoder/decoder อื่น ๆ ไม่ใช้ภาษาที่ไม่ปลอดภัย โอกาสที่จะสร้างบั๊กแบบนี้ก็จะลดลง
    • WebP เป็นฟอร์แมตที่ซับซ้อนกว่า JPEG มาก และ ความซับซ้อน แทบจะสัมพันธ์โดยตรงกับความหนาแน่นของข้อบกพร่อง
      นอกเหนือจากนั้น ผมคิดว่าวัฒนธรรมที่ทำให้โค้ดซับซ้อนเกินจำเป็น และนักพัฒนาที่ไม่เข้าใจรายละเอียดอย่างถูกต้องก็เป็นปัญหาด้วย
  • การแก้ไขนี้รวมอยู่ใน Firefox 117.0.1 และ Fenix 117.1.0 ของวันนี้: https://hg.mozilla.org/releases/mozilla-release/rev/e245ca21...

  • สำหรับข้อมูลเพิ่มเติม ใน image crate มี การใช้งานตัวถอดรหัส WebP ที่เขียนด้วย Rust ที่ปลอดภัย: https://github.com/image-rs/image
    แม้จะค่อนข้างยังไม่สมบูรณ์มาเป็นเวลานาน แต่ปีที่แล้วมีการ implement ฟีเจอร์ของ WebP จำนวนมาก
    ตอนนี้ Chromium มีนโยบายอนุญาตให้ใช้ dependency ของ Rust แล้ว บางที Chromium ก็น่าจะเริ่มนำมาใช้ได้ไม่ใช่หรือ?

    • ถ้า Chrome มีแฟล็กให้ “ใช้เวอร์ชันที่ปลอดภัยของไลบรารี XYZ แม้อาจช้ากว่า” ผมยอมรับการเสียประสิทธิภาพและจะเปิดใช้ทันที
    • ในปี 2023 การที่ยังเขียนโค้ด C/C++ ใหม่ต่อไปสำหรับเป้าหมายที่มี พื้นผิวการโจมตี ใหญ่โตอย่างเว็บเบราว์เซอร์นั้นรู้สึกว่าไม่สมเหตุสมผลเอาเสียเลย
  • คอมมิตต้นทางที่ก่อปัญหา: https://github.com/webmproject/libwebp/commit/f75dfbf23d1df1...
    คอมมิตที่แก้บั๊กนี้: https://github.com/webmproject/libwebp/commit/902bc919033134...
    คอมมิตต้นทางปรับแต่ง Huffman decoder ให้เหมาะสมขึ้น decoder นี้ใช้ optimization ที่เป็นที่รู้จักดี โดยอ่านล่วงหน้า N บิต แล้วตัดสินใจว่าจริง ๆ ต้อง consume กี่บิต และต้อง decode เป็น symbol ใด หรือถ้าเป็น prefix N บิตของหลาย symbol ก็จะตัดสินใจว่าต้องอ้างอิงตารางใดสำหรับบิตที่เหลือ
    เวอร์ชันเก่าใช้ lookup table สำหรับ symbol สั้น ๆ แต่ symbol ยาว ๆ ต้อง traversal ในกราฟ เวอร์ชันใหม่ปรับปรุงโดยใช้อาร์เรย์ของ lookup table แต่ละรายการเก็บ (nbits, value) โดย nbits คือจำนวนบิตที่จะ consume และ value โดยปกติคือ symbol แต่ถ้า nbits เกิน N จะตีความ value เป็น index ของตาราง และตีความ nbits ใหม่เป็นความยาวโค้ดที่ยาวที่สุดใน subtree นั้น ดังนั้นตารางถัด ๆ ไปแต่ละตารางต้องมีรายการ 2^(nbits - N) รายการ ส่วน root table จะถูกกำหนดตายตัวไว้ที่ 2^N รายการเสมอ
    เวอร์ชันใหม่คำนวณจำนวนรายการสูงสุด (kTableSize) จากจำนวน symbol แน่นอนว่า Huffman tree มาจาก input ที่เชื่อถือไม่ได้ และจินตนาการได้ง่ายว่ามีกรณีที่ nbits ใหญ่มาก โดยเฉพาะ VP8 Lossless อนุญาตได้สูงสุด 15 บิต ดังนั้นถ้า LUT ทั้งหมดถูก map ไปยังตารางเสริมแยกกันคนละชุด ตารางสูงสุดที่เป็นไปได้จะมี 2^N + 2^15 รายการ การสร้างแบบนี้ก็ไม่ได้ต้องใช้ symbol มากนัก แค่ 16-N symbol ต่อแต่ละตารางก็พอ
    ที่น่าสนใจคือในโค้ดเองมีโหมดที่คำนวณเฉพาะขนาดตาราง (เรียก VP8LBuildHuffmanTable ด้วย root_table == NULL) แต่ไม่รู้ทำไมจึงไม่ได้ใช้ และสมมติขนาดสูงสุดแบบคงที่ไว้แทน ดังนั้นถ้าสร้าง Huffman tree เพื่อ maximize จำนวนรายการ ก็จะเขียนล้นพื้นที่ที่ allocate ไว้
    เข้าใจได้ว่าทำไมเรื่องนี้ถึงเกิดขึ้น ขั้นตอน Huffman decoding เป็นหนึ่งในส่วนที่ใช้การคำนวณมากที่สุดในหลาย ๆ format บีบอัด ดังนั้น improvement เล็ก ๆ ก็สำคัญ optimization ข้างต้นเป็นที่รู้จักดี แต่ code path ที่ยาวมักถูกมองว่าเกิดขึ้นไม่บ่อย จึงมีลำดับความสำคัญในการ optimize ต่ำ ข้อความคอมมิตต้นทางแย้งสมมติฐานนี้และจึงถูก merge ได้ ยากจะมั่นใจได้ว่า ภาษาที่ปลอดภัยด้านหน่วยความจำ จะป้องกันปัญหานี้ได้หรือไม่ เพราะนี่เป็นกรณีที่พบไม่บ่อยซึ่งทำให้อยากหลีกเลี่ยง overflow check อย่างจริงจัง
    [1] อย่างไรก็ตาม memory corruption เกิดขึ้นระหว่างการสร้างตาราง ไม่ใช่ใน tight loop ดังนั้น overflow check บางส่วนก็น่าจะช่วยได้มาก การแก้ไขจริงไม่ได้เปลี่ยนฟังก์ชัน ReadSymbol เลย ถึงอย่างนั้น ความปลอดภัยของ tight loop ก็ต้องมีเหตุผลรองรับ และเหตุผลที่ผิดอาจทำให้ทุกอย่างพังได้

    • คอมโพเนนต์นี้ควรเขียนด้วย WUFFS
      ถ้าการบอกว่าไม่จำเป็นต้องมี boundary check นั้นถูกต้อง ก็โอเค WUFFS จะไม่ emit runtime boundary check
      แต่ถ้าซอฟต์แวร์ผิดพลาดจนออกนอกขอบเขตเหมือนครั้งนี้ ใน WUFFS จะ compile ไม่ผ่าน
      คุณอาจคิดว่า “นั่นเป็นไปไม่ได้” และถ้า WUFFS เป็นภาษาโปรแกรมมิงทั่วไป คำพูดนั้นก็ถูก ตามทฤษฎีบทของ Rice แล้ว semantic property ที่ไม่ trivial นั้นตัดสินไม่ได้
      โชคดีที่ WUFFS ไม่ใช่ภาษาทั่วไป ซอฟต์แวร์ส่วนใหญ่เขียนด้วย WUFFS ไม่ได้ แต่ image codec เขียนได้
    • ผมไม่ได้ทำงานเป็น C programmer มานานกว่า 10 ปีแล้ว และเดิมทีก็ไม่ได้เก่งนัก แต่จากคำอธิบาย ผมเห็นด้วยว่า boundary check น่าจะจับปัญหานี้ได้
      แต่ก็สงสัยเหมือนกันว่าอาจสร้าง automated test ที่จับปัญหาประเภทนี้ได้หรือไม่
      ในโค้ดที่ผมดูแลส่วนตัว สามารถแยก calculation บางส่วนออกเป็นฟังก์ชันต่างหากเพื่อทดสอบแยกได้ กรณีนี้อาจทำได้ยากเพราะ performance แต่ก็ไม่แน่ใจ
  • แก้ไข การเขียนนอกขอบเขต ใน BuildHuffmanTable
    https://github.com/webmproject/libwebp/commit/902bc919033134...

    • น่าสนใจด้วยว่ามีอีกคอมมิตหนึ่งที่เกี่ยวกับ oss-fuzz อยู่ถัดไปทันที: https://github.com/webmproject/libwebp/commit/95ea5226c87044...
      อาจหมายความว่า Google พบ bug นี้แล้วจึง optimize fuzzer สำหรับ libwebp และจากนั้นก็พบ bug เพิ่มอีก
  • ดูเหมือนว่า Apple เป็นผู้รายงาน และดูคล้ายกับ security update นี้มาก: https://support.apple.com/en-us/HT213906

    • Apple และ “Citizen Lab ของ UoT Munk School” เป็นผู้รายงาน ซึ่งในหน้าที่ลิงก์ก็ระบุไว้อย่างนั้นจริง ๆ
      ดังนั้นจึงดูมีความเป็นไปได้ค่อนข้างสูง Apple อาจใช้ libwebp ภายใน ImageIO หรืออาจทำพลาดในลักษณะคล้ายกัน
    • น่าสนใจที่ได้เห็นว่าปฏิกิริยาเมื่อสัปดาห์ที่แล้วกับตอนนี้แตกต่างกันแค่ไหน
  • image codec มี ประวัติช่องโหว่ที่ยาวนาน
    การประมวลผลภาพจริง ๆ อาจเป็นโค้ดเชิงเส้นที่เรียบร้อยพอจะเขียนด้วย FORTRAN IV ที่ปลอดภัยด้านหน่วยความจำได้ แต่พอมีการบีบอัดเข้ามา ก็จะมีโครงสร้างข้อมูลความยาวแปรผัน การไล่ตาม pointer และอื่น ๆ มากขึ้น
    แล้วยังมีแรงกดดันให้ต้องรันได้เร็วเพิ่มเข้ามาอีก

  • สิ่งนี้มีผลกระทบต่อ Electron ด้วยไหม? ถ้าใช่ เป็นเวอร์ชันไหน?

  • มีเส้นทางที่สามารถนำสิ่งนี้ไปใช้โจมตีจริงได้ไหม?
    ได้ยินมาว่าใน 64 บิต heap spraying ไม่ค่อยใช้งานได้จริงแล้ว
    มีอ็อบเจกต์ที่คาดเดาได้ในหน่วยความจำที่สามารถเขียนทับได้หรือเปล่า?

    • มันถูกนำไปใช้โจมตีในวงกว้างแล้ว ดังนั้นคำตอบคือใช่
      แม้บน 64 บิต heap spraying ก็ยังคงถูกใช้ใน kernel exploit อย่างชัดเจน ส่วนใน V8 exploit ผมไม่ค่อยรู้ว่าผู้คนใช้ primitive แบบไหนกัน