สรุปสั้น
Gitea แพลตฟอร์มจัดการซอร์สโค้ดแบบ Git ที่องค์กรนิยมติดตั้งใช้งานเอง ได้ออกแพตช์อุดช่องโหว่รันโค้ดจากระยะไกลระดับวิกฤต CVE-2026-60004 (CVSS 9.8) ซึ่งเปิดให้ผู้ใช้ที่มีสิทธิ์เขียน repository ตามปกติ เปลี่ยนเนื้อหา patch ที่ตัวเองควบคุมให้กลายเป็น Git hook ที่ทำงานจริง แล้วสั่งรันคำสั่งเชลล์ด้วยสิทธิ์ของบัญชีระบบปฏิบัติการที่ Gitea ใช้รันอยู่ ช่องโหว่นี้กระทบ Gitea ตั้งแต่เวอร์ชัน 1.17 เป็นต้นมาจนถึงก่อนเวอร์ชัน 1.27.1 และแก้ไขแล้วใน 1.27.1 โดยจุดที่ทำให้ความรุนแรงพุ่งขึ้นคือ แม้ API ที่มีช่องโหว่จะต้องยืนยันตัวตนและต้องมีสิทธิ์เขียน repo ก่อน แต่การตั้งค่าเริ่มต้นของ Gitea เปิดให้สมัครสมาชิกได้เอง คนนอกจึงเพียงสมัครบัญชีธรรมดาและสร้าง repo ของตัวเองบนระบบที่ยังไม่ถูกปรับแต่ง ก็โจมตีได้ทันทีโดยไม่ต้องมีข้อมูลรับรองใดๆ มาก่อน
ทางโครงการ Gitea แจ้งเมื่อวันที่ 27 กรกฎาคมว่าอินสแตนซ์บน Gitea Cloud จะถูกอัปเกรดให้โดยอัตโนมัติ ส่วนคำแนะนำด้านความปลอดภัยที่ออกตามมาในวันที่ 28 กรกฎาคมไม่ได้ระบุว่ามีการโจมตีจริงในธรรมชาติ แต่กลับมีโค้ดสาธิตการโจมตี (PoC) แบบสาธารณะแนบมาด้วย ผู้รายงานช่องโหว่คือนาย Shai Rod นักวิจัยด้านความปลอดภัยที่ใช้ชื่อว่า NightRang3r ซึ่ง Gitea ให้เครดิตไว้ในคำแนะนำ ทั้งนี้การปิดระบบสมัครสมาชิกแบบเปิดจะช่วยตัดช่องทางสร้างบัญชีสาธารณะระหว่างรอติดตั้งอัปเดตได้ก็จริง แต่ไม่ได้แก้ตัวช่องโหว่และไม่ได้ป้องกันผู้ใช้เดิมที่มีสิทธิ์เขียน repo อยู่แล้วแต่อย่างใด
รายละเอียดข่าว
เว็บไซต์ The Hacker News รายงานเมื่อวันที่ 29 กรกฎาคม 2569 ว่า Gitea ได้แพตช์ช่องโหว่รันโค้ดระยะไกลระดับวิกฤตที่อยู่ในเอนด์พอยต์ POST /api/v1/repos/{owner}/{repo}/diffpatch ซึ่งทำหน้าที่นำ patch ที่ผู้ใช้ส่งเข้ามาไปใช้กับ repository ตามคำแนะนำด้านความปลอดภัยของ Gitea เอง เอนด์พอยต์นี้จะนำ patch ไปประมวลผลภายในสำเนา clone ชั่วคราวแบบ bare ที่ใช้ร่วมกัน โดยเวอร์ชันที่มีช่องโหว่จะเรียก git apply พร้อมตัวเลือก --index, --recount, --cached และ --binary และจะเพิ่มตัวเลือกสำรองแบบสามทาง -3 เข้าไปด้วยเมื่อเซิร์ฟเวอร์รัน Git เวอร์ชัน 2.32 ขึ้นไป
เส้นทางที่ไม่ต้องมีข้อมูลรับรองมาก่อนนั้นเกิดจากการตั้งค่าเริ่มต้นของโครงการเอง ซึ่งเปิดให้สมัครสมาชิกได้อิสระ ไม่บังคับยืนยันอีเมล ไม่ต้องรอผู้ดูแลอนุมัติ ไม่ได้ทำเครื่องหมายผู้ใช้ใหม่ว่าเป็นบัญชีจำกัดสิทธิ์ และไม่ได้กำหนดเพดานจำนวน repository ที่สร้างได้ ส่วนเส้นทาง API ที่มีปัญหานั้นเรียกใช้ฟังก์ชัน reqToken() ซึ่งจะปฏิเสธคำขอที่ไม่มีผู้ใช้ล็อกอินอยู่เท่านั้น จึงไม่ได้เป็นอุปสรรคสำหรับผู้โจมตีที่สมัครบัญชีเองได้

โค้ด PoC ที่เผยแพร่ออกมาทำงานด้วยการล็อกอินด้วยบัญชีธรรมดา สร้าง repository แบบส่วนตัวที่ผ่านการเริ่มต้นค่าแล้ว ส่ง patch อันตรายเข้าไปสองครั้ง จากนั้นจึงดึงผลลัพธ์ของคำสั่งกลับออกมา จุดที่น่าสนใจคือมันไม่ต้องอาศัยการเรียกกลับออกสู่ภายนอก (outbound callback) เลย เพราะตัว hook จะเก็บผลลัพธ์ไว้ในอ็อบเจกต์ของ Git แล้วสร้าง branch ที่บรรจุผลลัพธ์นั้นไว้ ก่อนที่ผู้โจมตีจะดึงออกไปผ่าน smart HTTP ที่ผ่านการยืนยันตัวตนตามปกติ ซึ่งทำให้การตรวจจับด้วยการเฝ้าดูทราฟฟิกขาออกที่ผิดปกติแทบไม่ได้ผล
ข้อมูล ณ วันที่ 29 กรกฎาคม 2569 ยังไม่มีแหล่งข้อมูลปฐมภูมิใดที่รายงานว่าช่องโหว่นี้ถูกใช้โจมตีจริง ทั้งก่อนหรือหลังการปล่อยเวอร์ชัน 1.27.1 อย่างไรก็ตาม หากโจมตีสำเร็จ ผู้โจมตีจะได้สิทธิ์เทียบเท่าบัญชีระบบปฏิบัติการที่ Gitea ทำงานอยู่ ซึ่ง Gitea ระบุว่าขึ้นอยู่กับการแยกส่วนของอินสแตนซ์นั้นๆ ความเสียหายอาจลามไปถึงความลับของแอปพลิเคชันและตัวแปรสภาพแวดล้อม repository ที่ถูกเมาต์ไว้ ข้อมูลรับรองและเนื้อหาของฐานข้อมูล ข้อมูลรับรอง OAuth ตลอดจนบริการภายในอื่นๆ ที่เครื่องนั้นเข้าถึงได้
อีกประเด็นที่ผู้ดูแลระบบควรระวังคือ การแก้ไขนี้สังเกตได้ยากมากจากบันทึกการเปลี่ยนแปลง เพราะ Gitea เพียงเปลี่ยน clone ชั่วคราวจากแบบ bare ไปเป็นแบบไม่ bare พร้อมคอมเมนต์ในโค้ดที่เตือนไว้ชัดเจนว่าคำสั่ง Git ที่ใช้ --index อาจไปทำงานกับ working tree ได้ การเปลี่ยนแปลงนี้ถูกรวมเข้าโค้ดหลักและ backport เมื่อวันที่ 26 กรกฎาคม 2569 เวอร์ชัน 1.27.1 ปล่อยออกมาวันที่ 27 กรกฎาคม และคำแนะนำด้านความปลอดภัยตามมาวันที่ 28 กรกฎาคม โดยบันทึกการเปลี่ยนแปลงจัดรายการนี้ไว้ในหมวด MISC ว่า “refactor: git patch apply” ไม่ได้อยู่ในหมวด SECURITY แต่อย่างใด นอกจากนี้นาย Shai Rod ยังเคยแสดงตัวอย่างช่องโหว่ RCE ตัวนี้ควบคู่กับปัญหาการเรียกอ่านไฟล์ (file inclusion) อีกรายการ พร้อม PoC ที่ดึงไฟล์ /etc/passwd ออกจากโฮสต์ Gitea 1.27.0 ซึ่งดูเหมือนจะตรงกับการเปลี่ยนแปลงอีกจุดใน 1.27.1 ที่ปรับตัวเรนเดอร์ Org-mode ให้คืนค่า path ของ #+INCLUDE เป็นข้อความธรรมดาแทนการอ่านไฟล์จากระบบไฟล์ของเซิร์ฟเวอร์ โดย Gitea ยังไม่ได้ออกคำแนะนำหรือหมายเลข CVE แยกสำหรับปัญหานี้
รายละเอียดช่องโหว่
กลไกของช่องโหว่อยู่ที่การจงใจสร้างความขัดแย้งแบบ add/add ด้วยการส่ง patch ชุดเดียวกันเข้าไปสองครั้ง เมื่อ git apply เจอความขัดแย้ง มันจะถอยไปใช้กลไกผสานแบบสามทาง (three-way fallback) จากตัวเลือก -3 และกลไกนี้จะเช็กเอาต์ไฟล์ตาม path ที่อยู่ใน index ออกมาจริง ทั้งที่คำสั่งระบุ --cached ซึ่งตามความเข้าใจทั่วไปควรแตะเฉพาะ index ไม่ควรเขียนไฟล์ลงดิสก์
ความผิดพลาดนี้กลายเป็นการรันโค้ดได้เพราะ clone ชั่วคราวที่ Gitea สร้างขึ้นเป็นแบบ bare ซึ่งหมายความว่ารากของไดเรกทอรีนั้นคือ $GIT_DIR โดยตรง ดังนั้นไฟล์ที่ตั้งค่าให้รันได้และถูกวางไว้ที่ path hooks/post-index-change จึงตกลงไปอยู่ในไดเรกทอรี hook ของ Git พอดี และมีผลใช้งานทันที จากนั้น Git ก็จะรันไฟล์นั้นเองในระหว่างที่กำลังปรับปรุง index ทำให้คำสั่งเชลล์ของผู้โจมตีทำงานด้วยสิทธิ์ของบัญชีที่รันบริการ Gitea อยู่
เงื่อนไขที่ต้องครบสำหรับการโจมตีมี 4 ข้อ คือ ผู้โจมตีต้องมีสิทธิ์เขียน repository เซิร์ฟเวอร์ต้องรัน Git เวอร์ชัน 2.32 ขึ้นไปเพื่อให้ตัวเลือก -3 ถูกเพิ่มเข้ามา เส้นทาง API diffpatch ต้องเปิดใช้งาน และระบบไฟล์ชั่วคราวต้องเขียนได้และรันไฟล์ได้ ซึ่งทั้งหมดนี้เป็นค่ามาตรฐานของการติดตั้งทั่วไป และการเปิดสมัครสมาชิกตามค่าเริ่มต้นก็ทำให้คนนอกได้สิทธิ์เขียนที่จำเป็นบนระบบที่ไม่เคยปรับแต่งค่าใดๆ
ผลกระทบต่อไทย
Gitea เป็นทางเลือกยอดนิยมของหน่วยงานไทยที่ต้องการเก็บซอร์สโค้ดไว้ในองค์กรเองแทนการฝากไว้บนบริการคลาวด์ต่างประเทศ ทั้งด้วยเหตุผลด้านงบประมาณ ข้อกำหนดเรื่องการเก็บข้อมูลในประเทศ และนโยบายความมั่นคง จึงพบได้ทั่วไปทั้งในมหาวิทยาลัย หน่วยงานรัฐ บริษัทซอฟต์แวร์ขนาดกลางและเล็ก รวมถึงทีมพัฒนาภายในของธนาคารและผู้ให้บริการโทรคมนาคม โดยจำนวนไม่น้อยติดตั้งด้วย Docker แล้วเปิดพอร์ตออกอินเทอร์เน็ตเพื่อให้ทีมงานหรือผู้รับเหมาภายนอกเข้าถึงได้ ซึ่งเป็นรูปแบบเดียวกับที่เคยทำให้เกิดปัญหาในกรณี CVE-2026-20896 บน Gitea Docker image เมื่อต้นเดือนกรกฎาคมที่ผ่านมา
หากเซิร์ฟเวอร์ Gitea ถูกยึด ผลกระทบจะไม่ได้จบแค่ซอร์สโค้ดรั่ว เพราะเซิร์ฟเวอร์ประเภทนี้มักเก็บโทเคน CI/CD กุญแจ SSH สำหรับ deploy ข้อมูลรับรองฐานข้อมูล และไฟล์ตั้งค่าที่มีความลับของระบบงานจริง ผู้โจมตีจึงสามารถใช้เป็นหัวสะพานเข้าสู่ห่วงโซ่อุปทานซอฟต์แวร์ขององค์กร ด้วยการฝังโค้ดอันตรายลงใน repository แล้วปล่อยให้ระบบ build ส่งต่อไปยังระบบที่ใช้งานจริงหรือไปถึงลูกค้าปลายทาง ซึ่งเป็นรูปแบบการโจมตีที่ตรวจพบได้ยากและใช้เวลาสอบสวนนาน
คำแนะนำ
- อัปเกรด Gitea เป็นเวอร์ชัน 1.27.1 ทันที ซึ่งเป็นวิธีแก้ที่แท้จริงเพียงวิธีเดียว โดยเฉพาะระบบที่รัน 1.17 ขึ้นไป
- ระหว่างรออัปเกรด ให้ปิดการสมัครสมาชิกแบบเปิด (
DISABLE_REGISTRATION = true) เพื่อตัดช่องทางที่คนนอกจะสร้างบัญชีเอง แต่ต้องเข้าใจว่ายังไม่ได้แก้ช่องโหว่และไม่กันผู้ใช้ภายในที่มีสิทธิ์เขียนอยู่แล้ว - อย่าเปิดอินสแตนซ์ Gitea สู่อินเทอร์เน็ตโดยตรง ให้วางไว้หลัง VPN หรือ reverse proxy ที่มีการยืนยันตัวตนอีกชั้น
- ตรวจสอบไดเรกทอรี
hooks/ของ repository และ path ชั่วคราวว่ามีไฟล์แปลกปลอมที่รันได้หรือไม่ โดยเฉพาะไฟล์ชื่อpost-index-change - ไล่ดู log การเรียก API ย้อนหลังว่ามีการเรียก
diffpatchซ้ำติดกันสองครั้งจากบัญชีเดียวกันหรือไม่ และตรวจ branch ที่ถูกสร้างขึ้นผิดปกติ - รันบริการ Gitea ด้วยบัญชีที่มีสิทธิ์ต่ำสุด แยกคอนเทนเนอร์ ไม่แชร์ระบบไฟล์กับบริการอื่น และเมาต์พื้นที่ชั่วคราวแบบ noexec หากทำได้
- หากพบร่องรอยการโจมตี ให้หมุนเปลี่ยนความลับทั้งหมดที่เก็บบนเครื่อง ทั้งโทเคน CI/CD กุญแจ deploy ข้อมูลรับรองฐานข้อมูล และข้อมูลรับรอง OAuth
