10 คะแนน โดย GN⁺ 2024-07-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • บน GitHub สามารถเข้าถึงข้อมูลจากฟอร์กที่ถูกลบ รีโปซิทอรีที่ถูกลบ และแม้แต่รีโปซิทอรีแบบส่วนตัวได้
  • GitHub ทราบเรื่องนี้และเป็นพฤติกรรมที่ออกแบบไว้โดยตั้งใจ
    • เนื่องจากสิ่งนี้กลายเป็นช่องทางโจมตีขนาดใหญ่สำหรับทุกองค์กรที่ใช้ GitHub จึงมีการเสนอคำศัพท์ใหม่ว่า "Cross Fork Object Reference (CFOR)"
  • ช่องโหว่ CFOR เกิดขึ้นเมื่อฟอร์กหนึ่งของรีโปซิทอรีสามารถเข้าถึงข้อมูลสำคัญของอีกฟอร์กหนึ่งได้ รวมถึงข้อมูลจากฟอร์กแบบส่วนตัวและฟอร์กที่ถูกลบ

การเข้าถึงข้อมูลจากฟอร์กที่ถูกลบ

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

การเข้าถึงข้อมูลจากรีโปซิทอรีที่ถูกลบ

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

การเข้าถึงข้อมูลจากรีโปซิทอรีแบบส่วนตัว

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

ในทางปฏิบัติ เข้าถึงข้อมูลได้อย่างไร?

  • โดยการเข้าถึงคอมมิตโดยตรง
  • ในเครือข่ายรีโปซิทอรีของ GitHub การดำเนินการแบบทำลายล้าง (เช่น 3 สถานการณ์ที่กล่าวมาข้างต้น) จะลบการอ้างอิงถึงข้อมูลคอมมิตออกจาก UI มาตรฐานของ GitHub และจากการทำงาน git ทั่วไป
  • แต่ข้อมูลนี้ยังคงอยู่ และยังเข้าถึงได้หากรู้ค่า commit hash
  • commit hash เป็นค่า SHA-1 และหากผู้ใช้รู้ค่า SHA-1 commit hash ของคอมมิตที่ต้องการดู ก็สามารถเข้าถึงคอมมิตนั้นได้โดยตรงผ่านเอนด์พอยต์ https://github.com/<user/org>/…;
  • commit hash สามารถถูก brute force ได้ผ่าน UI ของ GitHub
  • และยังสามารถ query ค่า commit hash ได้ผ่าน public events API endpoint ของ GitHub

นโยบายของ GitHub

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

ผลกระทบ

  • ตราบใดที่ยังมีฟอร์กอยู่แม้เพียงหนึ่งฟอร์ก คอมมิตทั้งหมดในเครือข่ายรีโปซิทอรีนั้น (ไม่ว่าจะเป็นคอมมิตของรีโป "upstream" หรือของฟอร์ก "downstream") จะยังคงอยู่ตลอดไป
  • สถาปัตยกรรมรีโปซิทอรีของ GitHub จำเป็นต้องมีข้อบกพร่องด้านการออกแบบนี้ และผู้ใช้ GitHub ส่วนใหญ่ไม่เข้าใจว่าเครือข่ายรีโปซิทอรีทำงานอย่างไรจริง ๆ จึงมีแนวโน้มจะปลอดภัยน้อยลง
  • เมื่อ secret scanning พัฒนาไปจนสามารถสแกนคอมมิตทั้งหมดในเครือข่ายรีโปซิทอรีได้ ก็อาจแจ้งเตือนเกี่ยวกับ secret ที่ไม่ใช่ของตนเองได้
  • ทั้ง 3 สถานการณ์นี้แม้จะน่าตกใจ แต่ก็ยังไม่ครอบคลุมทุกวิธีที่ GitHub สามารถเก็บข้อมูลที่ถูกลบออกจากรีโปซิทอรีไว้ได้

ความเห็นของ GN⁺

  • บทความนี้ตั้งคำถามด้านความปลอดภัยที่สำคัญสำหรับองค์กรที่ใช้ GitHub การที่ข้อมูลจากรีโปซิทอรีที่ถูกลบหรือถูกตั้งค่าเป็นส่วนตัวยังเข้าถึงได้ถือว่าน่าตกใจ และดูเหมือนเป็นข้อบกพร่องเชิงออกแบบพื้นฐานจากสถาปัตยกรรมเครือข่ายรีโปซิทอรีของ GitHub
  • นักพัฒนาควรตระหนักถึงปัญหานี้และระมัดระวังเมื่อคอมมิตข้อมูลสำคัญหรือ secret ลงบน GitHub เพราะเมื่อถูก push ไปยังรีโปสาธารณะแล้ว ข้อมูลนั้นอาจเข้าถึงได้ตลอดไป หากมี secret สำคัญรั่วไหล วิธีแก้ที่สมบูรณ์มีเพียงการหมุนเวียนคีย์เท่านั้น
  • แม้ GitHub จะเปิดเผยและจัดทำเอกสารเรื่องนี้อย่างโปร่งใส แต่ผู้ใช้ส่วนใหญ่คงยังไม่เข้าใจอย่างถ่องแท้ว่าสถาปัตยกรรมเครือข่ายรีโปซิทอรีทำงานอย่างไร GitHub ควรพยายามมากกว่านี้ในการสร้างความตระหนักและให้ความรู้แก่ผู้ใช้เกี่ยวกับปัญหานี้
  • ปัญหาลักษณะคล้ายกันอาจมีอยู่ในระบบควบคุมเวอร์ชันอื่น ๆ ด้วย นักพัฒนาและองค์กรจึงควรเข้าใจสถาปัตยกรรมและข้อจำกัดของเครื่องมือที่ใช้อยู่ให้ดีเมื่อจัดการข้อมูลสำคัญ
  • เพื่อป้องกันการรั่วไหลของข้อมูลสำคัญ จำเป็นต้องมีมาตรการความปลอดภัยหลายด้าน เช่น การควบคุมสิทธิ์เข้าถึงอย่างเข้มงวด การใช้หลัก least privilege การสแกนหา secret และการมอนิเตอร์อย่างสม่ำเสมอ และเหนือสิ่งอื่นใดคือการมีความตระหนักด้านความปลอดภัยในระดับสูงของนักพัฒนา

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

 
GN⁺ 2024-07-25
ความเห็นจาก Hacker News
  • รายงานไปยัง HackerOne ตั้งแต่ปี 2018 แต่ GitHub ระบุว่าเป็นพฤติกรรมที่ตั้งใจไว้จึงไม่แก้ไข สรุปคือควรคัดลอกรีโพมาใช้แทนการทำ private fork
  • GitHub หมกมุ่นกับการทำให้ทุกอย่างเป็นสาธารณะและเปลี่ยนแปลงไม่ได้ ตัวอย่างเช่น หากต้องการลบคอมเมนต์ ต้องส่งอีเมลแนบเอกสารยืนยันตัวตนจริงไปยังเจ้าของรีโพ
  • ผู้ใช้ไม่ควรต้องมารับรู้ปัญหาแบบนี้ของฟีเจอร์ "private" และการที่ GitHub มองว่านี่เป็นฟีเจอร์ไม่ใช่บั๊ก แสดงให้เห็นถึงความไม่ใส่ใจเรื่องความปลอดภัย การเรียก private repository ว่าเป็น repository แบบ "ไม่แสดงในรายการ" อาจเหมาะสมกว่า
  • หากใช้ private repository และ private fork แล้วเปลี่ยนรีโพเป็นสาธารณะ ฟอร์กก็จะกลายเป็นสาธารณะด้วย แม้ GitHub จะอ้างว่าเป็นพฤติกรรมที่ตั้งใจไว้ได้ แต่ก็ควรบังคับให้ยืนยันการเปิดเผยทั้งรีโพและฟอร์กพร้อมกัน
  • พฤติกรรมนี้ดูคล้าย dark pattern และแม้เรื่องนี้จะกระทบต่อการทำมาหาเลี้ยงชีพของผู้คน GitHub ก็เหมือนไม่ใส่ใจ เพราะการปฏิเสธความรับผิดแบบมีช่องให้เลี่ยงและข้อกำหนดการใช้งานที่คลุมเครือมีค่ามากกว่าความเสียหายด้านชื่อเสียง
  • แปลกใจที่มีคอมเมนต์จำนวนมากพยายามลดทอนความสำคัญของปัญหานี้ แม้จะใช้ GitHub มานาน แต่ก็ไม่คาดคิดว่าจะเกิดผลลัพธ์แบบนี้และรู้สึกกังวล แนะนำให้อ่านบทความต้นฉบับด้วยตัวเอง
  • ปัญหานี้ไม่ใช่เรื่องใหม่ หลายคนเคยค้นพบมาก่อนแล้ว
  • OSPO ของ GitHub กำลังพัฒนา GitHub App แบบโอเพนซอร์สเพื่อคง private mirror ของ public fork ไว้ และมีแผนปล่อยเบต้าในสัปดาห์นี้
  • ช่องโหว่ที่แท้จริงคือวิธีที่ GitHub Events archive เปิดเผยค่าแฮช SHA1 ของรีโพที่เปราะบาง ทำให้สามารถค้นหาทั้งเครือข่ายเพื่อเข้าถึง private repository ที่ถูกลบไปแล้วได้
  • ปัญหาอยู่ที่ข้อมูล private สามารถพึ่งพาข้อมูล public ได้ ตัวอย่างเช่น ถ้า private commit พึ่งพา public commit C แล้ว C ถูกลบจากรีโพสาธารณะ GitHub ก็ต้องเก็บมันไว้ ไม่เช่นนั้น private commit จะเสียหาย
  • ทุก commit จะคงอยู่บน GitHub ตลอดไปหลังถูกส่งขึ้นไป และ commit ที่เคยเป็นสาธารณะแล้วจะเข้าถึงได้เสมอผ่าน commit hash