ในโลกของการพัฒนาซอฟต์แวร์ ระบบ continuous integration และ deployment ได้กลายเป็นเครื่องมือสำคัญสำหรับการรักษาคุณภาพและความปลอดภัยของโค้ด อย่างไรก็ตาม เหตุการณ์ด้านความปลอดภัยล่าสุดที่เกี่ยวข้องกับ GitHub Actions ได้เผยให้เห็นข้อบกพร่องพื้นฐานในวิธีที่ระบบเหล่านี้จัดการกับโค้ดที่ไม่น่าเชื่อถือ ซึ่งจุดประกายการถกเถียงอย่างเข้มข้นในหมู่ผู้เชี่ยวชาญด้านความปลอดภัยและนักพัฒนาซอฟต์แวร์เกี่ยวกับความปลอดภัยของเวิร์กโฟลว์การพัฒนาสมัยใหม่
ปัญหาของ pull_request_target
ปัญหาหลักเกี่ยวข้องกับทริกเกอร์ pull_request_target ของ GitHub ซึ่งผู้เชี่ยวชาญด้านความปลอดภัยให้ความเห็นว่ามีการออกแบบที่ไม่ปลอดภัยโดยพื้นฐาน แตกต่างจากทริกเกอร์ pull_request ที่ปลอดภัยกว่า pull_request_target ให้สิทธิ์การอ่าน/เขียนรีพอสิทอรีและการเข้าถึง secrets โดยค่าเริ่มต้น แม้ในขณะที่กำลังประมวลผล pull request จากฟอร์กที่ไม่น่าเชื่อถือ สิ่งนี้สร้างสถานการณ์อันตรายที่ผู้ไม่ประสงค์ดีสามารถใช้ประโยชน์จากช่องโหว่เพื่อเข้าถึงข้อมูลรับรองความลับและเนื้อหาในรีพอสิทอรีโดยไม่ได้รับอนุญาต
นี่เป็นตัวอย่างที่ดีว่าทำไม
pull_request_targetจึงไม่ปลอดภัยโดยพื้นฐาน และทำไม GitHub น่าจะลบทริกเกอร์นี้ออกไปเสียเลย
ปัญหายังถูกซ้ำเติมด้วยเอกสารประกอบของ GitHub ที่ทำให้เข้าใจผิด โดยแนะนำว่า pull_request_target ปลอดภัยกว่าเพราะทำงานในบริบทของ base branch แทนที่จะเป็น merge commit ผู้เชี่ยวชาญด้านความปลอดภัยให้ความเห็นว่าข้อมูลในเอกสารประกอบนี้ขาดความรับผิดชอบ เพราะทำให้เข้าใจว่าทริกเกอร์นี้ให้การป้องกันจากการโจมตีด้วยการดำเนินการโค้ด ในขณะที่ความจริงแล้วมันเพียงส่งเสริมให้นักพัฒนาดึงโค้ดที่ถูกควบคุมโดยผู้โจมตีมาทดสอบอย่างชัดเจน ซึ่งเป็นการสร้างช่องโหว่เพิ่มเติม
เปรียบเทียบ GitHub Action Triggers ที่สำคัญ:
pull_request: ทำงานด้วยสิทธิ์จำกัด ไม่สามารถเข้าถึง secrets ได้ตามค่าเริ่มต้นเมื่อประมวลผล forkspull_request_target: ทำงานด้วยสิทธิ์อ่าน/เขียนและสามารถเข้าถึง secrets ได้ตามค่าเริ่มต้น แม้กระทั่งสำหรับ PRs จาก fork
ความท้าทายของโมเดลทางความคิด
นักพัฒนาต้องเผชิญกับความท้าทายอย่างมีนัยสำคัญเมื่อเขียนเวิร์กโฟลว์ CI/CD สำหรับ pull request เพราะพวกเขาต้องสลับระหว่างสองบริบทความปลอดภัยที่แตกต่างกันอย่างต่อเนื่อง เมื่อเขียนขั้นตอนการทดสอบและการยืนยัน นักพัฒนามักทำงานภายใต้สมมติฐานว่าพวกเขากำลังเรียกใช้โค้ดที่น่าเชื่อถือจากทีมของตัวเอง อย่างไรก็ตาม เมื่อประมวลผล pull request จากภายนอก เวิร์กโฟลว์เดียวกันนี้กำลังเรียกใช้โค้ดที่อาจเป็นอันตรายจากแหล่งที่ไม่รู้จัก
ความขัดแย้งของโมเดลทางความคิดนี้กลายเป็นอันตรายอย่างยิ่งเมื่อเวิร์กโฟลว์จำเป็นต้องบูรณาการกับโครงสร้างพื้นฐานภายในสำหรับงานต่างๆ เช่น การทดสอบแบบ end-to-end หรือการตรวจสอบข้อตกลงของผู้มีส่วนร่วม ความซับซ้อนของการบูรณาการเหล่านี้ทำให้ง่ายต่อการสร้างช่องโหว่ด้านความปลอดภัยโดยไม่ได้ตั้งใจ ซึ่งการดำเนินการที่มีสิทธิพิเศษมีปฏิสัมพันธ์กับอินพุตที่ไม่น่าเชื่อถือ สถานการณ์นี้เป็นกรณีศึกษาคลาสสิกของความไม่ปลอดภัยที่ขับเคลื่อนโดยแรงจูงใจ - นักพัฒนาจำเป็นต้องดำเนินการที่สมเหตุสมผลกับผลงานจากบุคคลที่สาม แต่เครื่องมือที่มีอยู่กลับสร้างความเสี่ยงที่ไม่จำเป็น
เกินกว่าการดำเนินการโค้ดอย่างง่าย
ช่องโหว่ด้านความปลอดภัยขยายไปไกลกว่าการโจมตีด้วยการดำเนินการโค้ดอย่างง่าย ในเหตุการณ์ของ Nix ecosystem ผู้โจมตีค้นพบว่าพวกเขาสามารถใช้ประโยชน์จาก symbolic link ใน git repository เพื่ออ่านไฟล์ใดๆ ก็ตามบนระบบ runner โดยการแทนที่ไฟล์คอนฟิกด้วย symbolic link ที่ชี้ไปยังไฟล์ข้อมูลรับรองของ GitHub พวกเขาสามารถดึงโทเค็นการรับรองความถูกต้องที่มีสิทธิ์การอ่าน/เขียนรีพอสิทอรีทั้งหมดได้
ช่องโหว่ symbolic link นี้ส่งผลกระทบต่อเวิร์กโฟลว์เกือบทั้งหมดที่ประมวลผลผลงานจากภายนอก ซึ่งเป็นพื้นที่โจมตีขนาดใหญ่ที่นักพัฒนาจำนวนมากมองข้าม ปัญหาไม่ได้อยู่ที่ git เอง แต่อยู่ที่วิธีที่ระบบ CI/CD จัดการเนื้อหาในรีพอสิทอรีโดยไม่มีขอบเขตความปลอดภัยที่เหมาะสม แม้แต่เวิร์กโฟลว์ที่ไม่ได้ดำเนินการโค้ดจาก pull request อย่างชัดเจนก็ยังสามารถถูกโจมตีด้วยการจัดการระบบไฟล์ประเภทนี้ได้
รูปแบบช่องโหว่ที่พบบ่อย:
- การแทรก argument ผ่านเครื่องมืออย่าง xargs
- การโจมตีแบบ symbolic link ที่ทำให้สามารถสำรวจระบบไฟล์ได้
- การยกระดับสิทธิ์ผ่านการเปิดเผยข้อมูลรับรอง
- การแยกที่ไม่เพียงพอระหว่างการรันโค้ดที่เชื่อถือได้และไม่เชื่อถือได้
ข้อบกพร่องพื้นฐานในการออกแบบ
ผู้เชี่ยวชาญด้านความปลอดภัยชี้ให้เห็นถึงปัญหาที่ลึกซึ้งยิ่งขึ้นในวิธีที่ระบบ CI/CD สมัยใหม่จัดการกับการรับรองความถูกต้อง แนวทางปัจจุบันในการออก bearer token ให้กับโปรแกรมที่น่าเชื่อถือสร้างสถานการณ์ที่มีความเสี่ยงโดยธรรมชาติ ดังที่ผู้แสดงความคิดเห็นหนึ่งระบุไว้ หาก GitHub Actions จัดเตรียม privileged Unix sockets หรือการเข้าถึง ssh-agent แทนที่จะเป็น raw token ช่องโหว่ประเภทนี้จะถูกใช้ประโยชน์ได้ยากกว่ามาก
ปัญหายังถูกซ้ำเติมด้วยเครื่องมืออย่าง xargs ซึ่งหน้า man page ระบุไว้อย่างชัดเจนว่าไม่สามารถใช้ xargs อย่างปลอดภัยในบางบริบทได้ แม้การเพิ่ม -- argument delimiters จะช่วยลดความเสี่ยงบางอย่างได้ แต่สิ่งนี้ต้องการให้นักพัฒนาตื่นตัวเรื่องความปลอดภัยอยู่เสมอ ซึ่งเป็นแนวทางที่พิสูจน์แล้วว่าไม่เพียงพอในทางปฏิบัติหลายครั้ง ชุมชนด้านความปลอดภัยเปรียบเทียบเรื่องนี้กับการที่ต้องหลบหนี HTML ด้วยตนเองทุกที่เพื่อป้องกันการโจมตีแบบ XSS
ขั้นตอนการแก้ไขปัญหาเบื้องต้น:
- ปิดการใช้งาน workflows ที่มีช่องโหว่ในการตั้งค่า GitHub Action
- ตรวจสอบการใช้งาน pull_request_target triggers ทั้งหมด
- ใช้การตรวจสอบความถูกต้องของ argument อย่างเหมาะสม
- ใช้สิทธิ์เฉพาะที่จำเป็นเท่านั้น
- แยกการดำเนินการที่เชื่อถือได้และไม่เชื่อถือได้ออกจากกันอย่างสมบูรณ์
ก้าวไปสู่การแก้ปัญหา
ชุมชนด้านความปลอดภัยได้เสนอแนวทางหลายประการเพื่อแก้ไขปัญหาเหล่านี้ ผู้เชี่ยวชาญบางคนแนะนำให้ปิดใช้งาน pull_request_target อย่างสมบูรณ์ทั่วทั้งองค์กร ในขณะที่บางคนสนับสนุนให้ GitHub จัดเตรียมโทเค็นแบบละเอียด ใช้ครั้งเดียว ที่ออกแบบมาโดยเฉพาะสำหรับการดำเนินการที่ปลอดภัยกับ PR ของบุคคลที่สาม มีฉันทามติที่เพิ่มขึ้นว่าโมเดลการให้สิทธิ์แบบทั้งหมดหรือไม่ให้เลยในปัจจุบันไม่เพียงพอสำหรับเวิร์กโฟลว์การพัฒนาสมัยใหม่
องค์กรที่กังวลเกี่ยวกับช่องโหว่เหล่านี้สามารถดำเนินการได้ทันทีโดยไปที่การตั้งค่าองค์กรบน GitHub นำทางไปที่ Actions → General และปิดการใช้งาน actions ทั่วทั้งรีพอสิทอรีทั้งหมด วิธีการปุ่มตื่นตระหนกนี้ให้การป้องกันชั่วคราวในขณะที่ดำเนินการมาตรการความปลอดภัยถาวรมากขึ้น สำหรับความปลอดภัยอย่างต่อเนื่อง นักพัฒนาควรตรวจสอบเวิร์กโฟลว์ของพวกเขาอย่างละเอียด ลดสิทธิ์ให้เหลือน้อยที่สุด และแยกการดำเนินการที่น่าเชื่อถือออกจากการดำเนินการที่ไม่น่าเชื่อถืออย่างเคร่งครัด
การอภิปรายที่กำลังดำเนินอยู่เน้นย้ำถึงความตึงเครียดระหว่างความสะดวกของนักพัฒนาและความปลอดภัยในการพัฒนาซอฟต์แวร์สมัยใหม่ ในขณะที่ระบบ CI/CD กลายเป็นส่วนสำคัญมากขึ้นในกระบวนการพัฒนา การค้นหาความสมดุลที่เหมาะสมระหว่างฟังก์ชันการทำงานและความปลอดภัยยังคงเป็นความท้าทายเร่งด่วนสำหรับอุตสาหกรรมทั้งหมด
อ้างอิง: Pwning the Entire Nix Ecosystem
