1 คะแนน โดย GN⁺ 2025-07-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • แนะนำเทคนิคการโจมตีที่อาศัย อักขระ carriage return ภายใน Git repository
  • ช่องโหว่นี้ทำให้เกิดความเป็นไปได้ของ การรันโค้ดจากระยะไกล (RCE)
  • มีการรันคำสั่งอันตรายระหว่าง กระบวนการ git clone บางกรณี
  • ยืนยันผลกระทบใน สภาพแวดล้อม Linux และ Windows
  • เน้นย้ำความเสี่ยงของ การจัดการ Git repository ที่มีช่องโหว่ด้านความปลอดภัย

อักขระ Carriage Return และช่องโหว่ของ Git

  • สามารถสร้าง ชื่อไฟล์ที่มีอักขระ carriage return (\r) รวมอยู่ ภายใน Git repository ได้
  • เมื่อโคลน repository ที่มีชื่อไฟล์ลักษณะนี้ด้วย git clone อาจทำให้เกิด การรันคำสั่งที่ไม่ตั้งใจ จากความผิดพลาดในกระบวนการตีความคำสั่ง

สถานการณ์การรันโค้ดจากระยะไกล (RCE)

  • ผู้โจมตีเพิ่มไฟล์ที่แทรกอักขระ carriage return แล้วคอมมิตเข้าไปใน repository
  • หากผู้ใช้ git clone repository นี้ อาจเกิดความเสี่ยงของ การรันโค้ดที่ไม่พึงประสงค์ เนื่องจากระบบไฟล์และคำสั่ง git ตีความผิดพลาด
  • โดยเฉพาะอย่างยิ่ง สามารถชักจูงให้ สคริปต์ hook (เช่น โค้ดในโฟลเดอร์ .git/hooks) ทำงานอัตโนมัติได้

สภาพแวดล้อมที่ได้รับผลกระทบและการรับมือ

  • สามารถเกิดขึ้นได้กับ git บนระบบปฏิบัติการหลากหลาย เช่น Linux และ Windows
  • เป็น ภัยคุกคามด้านความปลอดภัยร้ายแรง สำหรับนักพัฒนาและองค์กรที่ดูแล Git repository หรือโคลน repository ภายนอกอยู่บ่อยครั้ง

คำแนะนำด้านความปลอดภัย

  • เมื่อต้องโคลน Git repository ภายนอกที่ไม่น่าเชื่อถือ ควร ใช้เวอร์ชันล่าสุดและตรวจสอบสถานะความปลอดภัย
  • ควรตรวจจับและตรวจสอบชื่อไฟล์ที่มีอักขระผิดปกติภายใน repository (โดยเฉพาะ carriage return) ก่อนทำการโคลน

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

 
GN⁺ 2025-07-09
ความคิดเห็นบน Hacker News
  • จากผลทั้งหมดนี้ มีการอธิบายว่าระหว่างทำ submodule clone จะเกิดอาการที่ตอนอ่านใช้ path = ... แต่ตอนเขียนกลับบันทึกไปยังอีกพาธหนึ่งที่ไม่ได้ลงท้ายด้วย ^M

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

    • แม้ยังไม่ได้เผยแพร่ PoC แต่มีการบอกว่าเป็นการดัดแปลง exploit ของ CVE-2024-32002 แทบจะตรง ๆ และเทสต์ใน commit ที่ใช้แก้ก็ให้คำใบ้สำคัญมาก

    • อ้างคำอธิบายของ CVE-2024-32002: สามารถดัดแปลง repository ที่มี submodule อย่างประสงค์ร้ายเพื่อใช้บั๊กของ Git เขียนไฟล์ลงในไดเรกทอรี .git/ แทนที่จะเป็น submodule worktree ได้ ทำให้สามารถเขียน hook ที่จะถูกรันทันทีระหว่างการ clone จนผู้ใช้ไม่มีโอกาสได้ตรวจสอบโค้ดที่จะถูกรันจริง ๆ

    • สรุปคือสามารถใส่ git hook ที่เป็นอันตรายลงใน repository ได้ และโดยปกติ git hook จะไม่ถูกติดตั้งตอน git clone แต่การโจมตีครั้งนี้ทำให้สิ่งนั้นเกิดขึ้นได้ จึงมีความเป็นไปได้ที่ hook จะถูกรันระหว่างขั้นตอน clone

    • ดูข้อมูลเพิ่มเติมเกี่ยวกับ CVE ใหม่นี้ได้ที่นี่

      • อธิบายว่าเวลา Git อ่านค่าคอนฟิกจะลบอักขระ CR และ LF ออก แต่ตอนเขียนกลับไม่ได้ quote CR จึงทำให้ข้อมูลสูญหายตอนอ่าน
      • หาก path ของ submodule ลงท้ายด้วยอักขระ CR จะมีการใช้ path ที่ถูกลบอักขระนั้นออก ทำให้ submodule อาจถูก checkout ไปยังตำแหน่งที่ผิด
      • ถ้ามี symlink อยู่แล้วระหว่าง path ที่ถูกลบนั้นกับไดเรกทอรี hook ของ submodule ผู้โจมตีสามารถรันโค้ดตามอำเภอใจผ่าน post-checkout hook ได้
      • มีความเห็นว่านอกจาก CVE นี้แล้ว ยังมีช่องโหว่อื่น ๆ ของ Git อีกมากที่ควรดูไปพร้อมกัน
    • มีการพูดถึงความจริงที่เรียบง่ายแต่ชวนอึดอัดว่า ถ้าเขียนไฟล์ตามอำเภอใจได้ ส่วนใหญ่ก็มักต่อยอดไปถึง RCE ได้

  • กล่าวถึงความเสี่ยงของการใช้ ad-hoc DSL ในการเขียนไฟล์คอนฟิก

    • ชี้ว่ามักไม่มีสเปกอย่างเป็นทางการสำหรับไวยากรณ์ และมาตรฐานที่แท้จริงของการ parse มักกระจัดกระจายอยู่ใน implementation สำหรับ serialization/deserialization ที่ทำขึ้นเอง

    • เน้นว่าถ้าทั้งสองส่วนไม่สอดคล้องกันเอง เช่น parser รองรับไวยากรณ์ใหม่แต่ writer ยังไม่รองรับ ความต่างของ parser ก็อาจกลายเป็นระเบิดเวลาได้

    • บทเรียนคือควรมี source of truth เพียงจุดเดียว และส่วนที่พึ่งพามันควรถูกสร้างอัตโนมัติจากจุดนั้น

    • มีการชี้ว่าบั๊กนี้เป็นคนละเรื่องกับปัญหา source of truth

      • เป็นข้อผิดพลาดเชิงตรรกะล้วน ๆ และอธิบายว่าถ้าบน Unix มี standard system library แบบนี้อยู่ ปัญหาเดียวกันก็อาจเกิดขึ้นได้เหมือนกัน
      • หากมันอยู่ใน standard library แบบนั้นจริง ผลกระทบคงร้ายแรงกว่านี้มาก และตอนนี้ความเสียหายยังค่อนข้างจำกัดอยู่ในกลุ่มนักพัฒนาเป็นหลัก
    • มีความเห็นว่า DSL ที่ใช้ที่นี่ (ฟอร์แมตไฟล์ ini) แม้จะเป็น ad-hoc แต่ก็พบได้ทั่วไป คุ้นเคย และจัดระเบียบไว้อย่างดี จนโดยทั่วไปถือเป็นสเปกโดยพฤตินัยได้เพียงพอ

      • แก่นของบั๊กไม่ใช่ตัวฟอร์แมต แต่คือ parser (หรือ lexer) แบบเขียนมือที่สอดแทรกอยู่ตรงกลาง และควรเลิกเขียนโค้ดแบบนี้ได้แล้ว
      • แม้ยังมีบางจุดที่จำเป็นต้องเขียนแบบ clever ด้วยมือ แต่ไม่ควรใช้กับฟอร์แมตแลกเปลี่ยนข้อมูลเด็ดขาด ถ้าต้องการ ini ก็ใช้ toml ถ้าไม่ชอบก็ JSON แม้แต่ YAML ก็ยังได้ ถ้าอยากทรมานจริง ๆ ก็ XML และถ้ายืนยันว่าต้องเป็นไบนารีฟอร์แมตก็ไปใช้ protobufs
      • สรุปคือถ้าไม่ใช่ผู้เขียนภาษาโปรแกรมเอง ก็ไม่ควรเขียน parser ด้วยตัวเอง และควรใช้ไลบรารีให้ได้
  • มีคนลองทำซ้ำปัญหาด้วยตัวเองแล้วอัปขึ้นrepository นี้

    • รีบพยายามอัปเดตไปใช้ Git เวอร์ชันล่าสุดทันที แต่บน Arch ยังไม่มี

    • ตั้งใจจะงด pull ไปก่อนจนกว่าจะมีแพตช์ใหม่ เพราะกังวลว่า repository ดัง ๆ ที่ตั้ง auto pull ไว้อาจมีปัญหา และคงต้องใช้เวลานานกว่าจะอัปเกรดกันครบ

    • มีการตั้งข้อสงสัยว่าช่องโหว่นี้ถูกเปิดเผยก่อนแพตช์หรือไม่

      • แต่ก่อนบทความที่อธิบายว่าใครจะโจมตีช่องโหว่ได้อย่างไรมักออกมาหลังแพตช์ไปแล้วหลายเดือน จึงอยากให้ทุกวันนี้ทุกโพสต์ช่วยระบุให้ชัดแบบผ่าน ๆ ว่า "อันนี้อันตรายจริงตอนนี้" หรือ "มีแพตช์แล้วไม่ต้องกังวล" เพื่อแยกกันให้ชัด
  • จากคำพูดที่ว่าเป็นแค่ "การดัดแปลงง่าย ๆ" ของ exploit เดิม จึงมีคนสงสัยว่าทำไม Git ไม่ใช้ Landlock (ฟีเจอร์ sandbox ด้านความปลอดภัยบน Linux)

    • เสนอว่า git clone ควรถูกจำกัดให้มีสิทธิ์อ่านอย่างเดียวในไดเรกทอรีคอนฟิก มีสิทธิ์อ่าน/เขียนเฉพาะไดเรกทอรีปลายทางของ clone และห้ามเรียก subprocess

    • ประชดว่าทำไม exploit ชอบลงเอยด้วยการเปิดเครื่องคิดเลขตลอด

    • มีคนทักว่าถ้าห้ามเรียก subprocess ก็จะทำให้ git hook ทุกชนิด เช่น post-checkout ใช้งานไม่ได้

      • อธิบายว่าถ้าไม่ต้องการความสามารถเหล่านั้น ก็อาจรัน git ในสภาพแวดล้อมแบบคอนเทนเนอร์อย่าง seccomp ได้ แต่หลายฟีเจอร์จะถูกจำกัด
    • และยังชี้ว่าถ้าไม่มี subprocess ก็จะใช้ git ผ่าน ssh ไม่ได้ด้วย

  • มีการถามว่า Homebrew เองได้รับผลกระทบหรือไม่ (กล่าวคือมีการทำ recursive clone หรือเปล่า)

    • พบความเป็นไปได้จากโค้ดนี้

    • มีความเห็นว่าเป้าหมายของ Homebrew ก็คือการรันโค้ดจาก repository อยู่แล้ว ถ้าไม่มี recursive clone กลับจะดูแปลกเสียมากกว่า

      • ประเด็นคือ RCE จะมีความหมายก็ต่อเมื่อข้อมูลที่ clone มาไม่ควรถูกรัน แต่กรณีแบบนั้นพบไม่บ่อยนัก
  • อ่านคำกล่าวของ Jon Postel เรื่อง CR+LF แล้วนึกย้อนความหลัง

    • แชร์ลิงก์บทความนี้ พร้อมความเห็นว่าเมื่อเทียบกับปี 2003 คำแนะนำนั้นอาจไม่เหมาะกับปัจจุบันแล้ว
    • เชื่อมโยงกับคำอธิบายที่ Mark Crispin เคยให้ไว้ในตอนนั้นว่าผู้คนกำลังเข้าใจผิด และกับกรณีที่ Daniel J. Bernstein เคยชี้ปัญหาที่เกิดจากกระบวนการแปลงระหว่างมนุษย์กับเครื่อง (parsing/quoting) ตั้งแต่ปลายทศวรรษ 1990
    • สังเกตว่าแม้ผ่านไป 25 ปี ปัญหาในโค้ด quoter ที่ไม่ escape CR ก็ยังวนกลับมาอีก และแม้หลังแก้แล้วก็ยังไม่ได้ตรวจอักขระ whitespace ทั้งหมด
    • จากผล git blame พบว่าโค้ดที่เป็นปัญหาถูกเขียนไว้เมื่อ 19 ปีก่อน ซึ่งตรงกับช่วงครบรอบ 10 ปีที่ Bernstein เขียนทบทวนเรื่องนี้
    • แชร์ข้อมูลเพิ่มเติมอย่างcommit ที่เกี่ยวข้อง, บทความ qmail เป็นต้น
    • ย้ำว่าท้ายที่สุดเราก็ยังต้องกลับมาเรียนบทเรียนยาก ๆ ของศตวรรษที่ 20 ซ้ำอีกครั้งในศตวรรษที่ 21
  • ดูเหมือนจะต้องรออีกหน่อย เพราะ Homebrew ยังไม่มีอัปเดต Git 2.50.1

    • แนะนำให้ลองอัปเดตผ่านissue นี้ หรือ brew install git --HEAD
  • มีการแชร์ว่า Homebrew และ Debian Bookworm ยังแจกจ่ายเวอร์ชันที่มีช่องโหว่อยู่ทั้งคู่

    • ตอนนี้ Homebrew ก็ใช้เวอร์ชัน 2.50.1 ได้แล้ว
  • มีการครุ่นคิดว่าหาก system call ที่ใช้ดึงรายการไดเรกทอรีพบว่ามีอักขระควบคุม ASCII (bytes) อยู่ในชื่อไฟล์ ควรปฏิเสธการมีอยู่ของไฟล์นั้น มองว่าเป็นดิสก์เสียหาย หรือควรจัดการแบบอื่น

    • เสนอว่าใน locale ปัจจุบัน byte เหล่านั้นอาจมีความหมายอย่างอื่นได้ จึงอาจเกิดสถานการณ์คาดไม่ถึง เพราะไม่ได้สมมติว่าชื่อไฟล์ทั้งหมดเป็น UTF-16 แบบ Windows

    • มีคนชี้สั้น ๆ ว่าปัญหานี้เกิดจากการที่บนระบบตระกูล Unix ชื่อไฟล์ (รวมถึงสตริงอื่น ๆ) เป็นเพียงอาร์เรย์ของไบต์ธรรมดาเท่านั้น