- มีข้อชี้ว่า การแจ้งเตือนที่มากเกินไปของ Dependabot ทำให้นักพัฒนาเสียเวลามากกว่าการแก้ปัญหาความปลอดภัยจริง
- ดังเช่นกรณีใน ecosystem ของ Go ที่มีการสร้าง PR และคำเตือนนับพันรายการแม้ใน repository ที่ไม่ได้รับผลกระทบ จนก่อให้เกิดความสับสน
- หากใช้ GitHub Action ที่อิงกับ govulncheck ก็จะตรวจจับได้เฉพาะโค้ดที่มีช่องโหว่จริง และตัดคำเตือนที่ไม่จำเป็นออกได้
- การจัดการอัปเดต dependency จะปลอดภัยและมีประสิทธิภาพกว่าหากดูแลด้วย การทดสอบเป็นระยะและการตรวจสอบเวอร์ชันล่าสุด แทน PR อัตโนมัติ
- แนวทางนี้สำคัญต่อการลด ความล้าจากการแจ้งเตือน (alert fatigue) และบรรเทาภาระของผู้ดูแลโอเพนซอร์ส
ปัญหาของ Dependabot
- Dependabot สร้างคำเตือนด้านความปลอดภัยและ PR อัตโนมัติจำนวนมาก จนทำให้นักพัฒนาแยกแยะได้ยากว่าเรื่องใดสำคัญจริง
- แม้เป็นการแก้ไขเล็กน้อยของแพ็กเกจ Go
filippo.io/edwards25519 ก็ยังทำให้เกิด PR หลายพันรายการ
- ยังมีการส่งคำเตือนความปลอดภัยที่ผิดพลาดไปยัง repository ที่ไม่ได้รับผลกระทบด้วย เช่น Wycheproof
- ในคำเตือนยังมี คะแนน CVSS ที่คลาดเคลื่อนและตัวชี้วัดความเข้ากันได้ที่ต่ำ ซึ่งสร้างความกังวลโดยไม่จำเป็น
- การแจ้งเตือนที่มากเกินไปเช่นนี้ถูกชี้ว่าเป็นสาเหตุที่ ลดความน่าเชื่อถือและประสิทธิภาพของการตอบสนองด้านความปลอดภัย
ทางเลือกด้วย govulncheck
- Go Vulnerability Database ให้ เมทาดาทาที่ละเอียดในระดับเวอร์ชัน แพ็กเกจ และสัญลักษณ์
- ตัวอย่างเช่น ช่องโหว่
GO-2026-4503 ส่งผลเฉพาะกับสัญลักษณ์ Point.MultiScalarMult เท่านั้น
- govulncheck ใช้การวิเคราะห์แบบสถิติเพื่อตรวจจับเฉพาะโค้ดที่มีช่องโหว่ซึ่งสามารถถูกเรียกใช้งานได้จริง
- เมื่อใช้ร่วมกับ
go mod why ก็สามารถตัดสินได้อย่างแม่นยำว่า dependency ทางอ้อมได้รับผลกระทบหรือไม่
- จากผลการตรวจสอบ แม้จะมีช่องโหว่อยู่ แต่หากโค้ดไม่ได้เรียกใช้สัญลักษณ์นั้น ก็จะไม่แจ้งเตือน
- สามารถผสานรวมได้ง่ายผ่าน CLI (
govulncheck -json) หรือ Go API (golang.org/x/vuln/scan)
การแทนที่ด้วย GitHub Actions
- แทนที่จะใช้ Dependabot สามารถตั้งค่า govulncheck GitHub Action ให้ตรวจสอบอัตโนมัติทุกวันได้
- จะส่งการแจ้งเตือนเฉพาะเมื่อพบช่องโหว่จริงเท่านั้น
- ไม่สร้าง PR อัตโนมัติ ทำให้นักพัฒนา โฟกัสกับประเด็นความปลอดภัยที่สำคัญ ได้มากขึ้น
- การลดคำเตือนผิดพลาดช่วยบรรเทา ความล้าจากการแจ้งเตือนด้านความปลอดภัย (alert fatigue) และยกระดับคุณภาพการรับมือ
- ยังช่วยแก้ปัญหาการส่ง PR ที่ไม่จำเป็นไปยังผู้ดูแลโอเพนซอร์สอีกด้วย
วิธีจัดการการอัปเดต dependency
- ควรจัดการ dependency แบบรวมตาม รอบการพัฒนาของแต่ละโปรเจกต์
- ทดสอบกับเวอร์ชันล่าสุดทุกวัน แต่ทำการอัปเดตจริงเฉพาะเมื่อถึงเวลาที่จำเป็น
- ใน Go สามารถทดสอบเวอร์ชันล่าสุดด้วย
go get -u -t ./... และใน npm ใช้คำสั่ง npm update
- วิธีนี้ช่วยรักษาได้ทั้ง ความเร็วในการรับมือช่องโหว่และความเสถียร
- การทดสอบกับเวอร์ชันล่าสุดช่วยค้นหาปัญหาความเข้ากันได้ตั้งแต่เนิ่น ๆ
- ป้องกันไม่ให้ dependency ที่มีโค้ดอันตรายถูกนำขึ้นใช้งานจริงทันที
- หากใช้ geomys/sandboxed-step ก็สามารถรันแบบแยกสภาพแวดล้อมด้วย gVisor ใน CI ได้
บทสรุปและเบื้องหลังการสนับสนุน
- ระบบอัตโนมัติของ Dependabot หลายครั้งก่อให้เกิด noise มากกว่าความปลอดภัย
- แนวทางที่อิงกับ govulncheck และการทดสอบเป็นระยะ เป็นวิธีจัดการความปลอดภัยที่แม่นยำและยั่งยืนกว่า
- การดูแลโอเพนซอร์สของผู้เขียนบทความนี้ดำเนินต่อได้ผ่านองค์กร Geomys โดยได้รับการสนับสนุนจาก Ava Labs, Teleport, Tailscale, Sentry และรายอื่น ๆ
- โมเดลเช่นนี้มีส่วนช่วยให้ ระบบนิเวศโอเพนซอร์สคงความมั่นคงและยกระดับคุณภาพด้านความปลอดภัย
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
แต่เครื่องมือที่แค่เทียบหมายเลขเวอร์ชันกับฐานข้อมูลช่องโหว่ ไม่สามารถตัดสินได้ว่าโค้ดจริงได้รับผลกระทบจากช่องโหว่นั้นหรือไม่ จึงมี สัญญาณรบกวนเยอะ
เครื่องมือที่น่าประทับใจเมื่อไม่นานมานี้คือ CodeQL สามารถรันได้ใน GitHub Advanced Security และติดตามการไหลจริงของโค้ดเพื่อ แสดงเส้นทางทั้งหมดแบบภาพ ว่าค่าอินพุตนำไปสู่การใช้งานที่เสี่ยงอย่างไร
ทำให้ได้ข้อมูลที่นำไปแก้ไขจริงได้และมี false positive น้อย แน่นอนว่าในภาษาที่เป็น dynamic อย่าง Python ก็ยังมีโค้ดที่หลบการตรวจจับได้ แต่ในกรณีส่วนใหญ่ก็ยังมีประโยชน์มาก
มีคอมเมนต์แนวให้เพิ่มตัวแปรกลางที่ไม่มีประโยชน์ แค่เพื่อหลบคำเตือนของ CodeQL รู้สึกเหมือนเป็น เครื่องมือที่ overfit กับข้อมูล
debugอยู่ และมี รายงาน ReDoS มั่ว ๆ เยอะมาก บางอันถึงขั้นมีการออก CVE เลย จนรู้สึกอยากถอนตัวจาก ecosystem ของ JSผมสร้าง GitHub Action ที่ใช้แจ้งเตือนเมื่อมีการเพิ่มการเรียกใช้ที่มีช่องโหว่เข้ามาใน PR แล้วใช้งานอยู่
ถ้าใช้คู่กับการ auto-merge ของ Dependabot ก็เป็นชุดที่ใช้จัดการโค้ดเบส JS ได้ดีเหมือนกัน
ถ้ามีเทสต์เพียงพอ บางทีก็เจอบั๊กในเวอร์ชันใหม่ แต่ระหว่างทางก็อาจต่อยอดไปเป็น การมีส่วนร่วมกับโอเพนซอร์ส ได้ด้วย น่ารำคาญก็จริง แต่ช่วยสร้างนิสัยที่ดี
การแจ้งเตือนทางอีเมลน่ารำคาญ และผมก็ไม่ชอบให้ PR กองพะเนิน อยากจัดการแบบรวมทีเดียวในช่วงเวลาที่กำหนดมากกว่า
dependabot.ymlเพื่อปรับรอบการทำงานและจำนวน PR ได้ดู เอกสารทางการ
จะใช้วิธีแก้เองเพื่อลดจำนวน issue ก็ได้เหมือนกัน
ส่วนตัวผมแนะนำ Renovate เพราะรองรับภาษาได้มากกว่าและมีตัวเลือก auto-merge
ปัญหาพื้นฐานของ Dependabot คือมันมองการจัดการ dependency ผิดเป็นปัญหาความปลอดภัย
ช่องโหว่ในฟังก์ชันที่ไม่ถูกเรียกใช้งานไม่ใช่ประเด็นด้านความปลอดภัย แต่เป็น สัญญาณรบกวน
ใน Python รู้สึกว่า
pip-audit --descดีกว่า Dependabotจนกว่าจะมี static analysis ที่สมบูรณ์ การ ตรวจสอบด้วยมือรายไตรมาส อาจปลอดภัยกว่าด้วยซ้ำ
ตรงนี้เองที่เกิดช่องว่างระหว่างความปลอดภัยจริงกับ แนวปฏิบัติด้านความปลอดภัย
CVE ส่วนใหญ่ไม่ได้ส่งผลจริง แต่บริษัทต่าง ๆ กลับพยายามทำให้จำนวนช่องโหว่ใน container image เป็น 0
แถมพออัปเดต dependency ก็มักมี CVE ใหม่โผล่มาอีกอยู่ดี เพราะซอฟต์แวร์ส่วนใหญ่ ไม่ทำ backport patch
ยิ่งมีรีโพเยอะและมีหลายภาษา การเพิ่ม CI workflow ที่สมบูรณ์ให้ครบทุกที่ยิ่งไม่สมจริง
ถึงจะไม่สมบูรณ์แบบ แต่ผมคิดว่าก็ดีกว่าไม่ทำอะไรเลยมาก
มันสร้าง CVE อัตโนมัติหรือเปล่า?
ฐานข้อมูลช่องโหว่ของ GitHub เน้นปริมาณมากกว่าคุณภาพ และ Dependabot ก็ทำงานเหมือน เครื่องส่งสแปมแจ้งเตือนที่ไร้สติ
ถ้าต้องเรียกฟังก์ชันผิดวิธีถึงจะเกิดปัญหา ก็มีโอกาสสูงที่โค้ดเดิมจะใช้งานไม่ได้อยู่แล้ว
การสแกน container image ของ GCP ยิงคำเตือน CVE จำนวนมากเข้า Vanta แต่ส่วนใหญ่แก้ไม่ได้ หรือเป็นเส้นทางที่ไม่ได้ใช้งานจริง
เลยสงสัยว่ามีเครื่องมือที่ช่วยทำ การกรองตามบริบท แบบนี้หรือไม่
โดยรวมผลลัพธ์ค่อนข้างดี แต่เพราะโค้ดเบสใหญ่และมี dependency เยอะ การลดจำนวน CVE ก็ยังยากอยู่ดี