เจาะเบื้องหลังเครื่องมือสแกนช่องโหว่ AI ที่พลาดบั๊กถึง 93% ในรอบแรก
นักพัฒนาเผยบทเรียนจากการสร้างเครื่องมือสแกนความปลอดภัยด้วย AI ที่ได้คะแนน Recall ต่ำเตี้ยเรี่ยดินในรอบแรก แต่กลับเป็นผลลัพธ์ที่ถูกต้องและมีค่าที่สุดในการเริ่มต้น

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- รันสแกนเนอร์รอบแรกพบคะแนน Recall แค่ 0.07 หรือพลาดบั๊กไปถึง 93% เต็มๆ
- เครื่องมือนี้ออกแบบให้กฎวิเคราะห์เชิงสถิตทำงานร่วมกับ LLM เพื่อคัดกรองผลลัพธ์
- สาเหตุหลักมาจากรายการ Source ที่จำกัดเกินไป ไม่ใช่ปัญหาโครงสร้างระบบหลัก
- เลือกเปิดเผยผลลัพธ์ที่ย่ำแย่ตรงๆ เพื่อสร้างความโปร่งใสและน่าเชื่อถือในระยะยาว
เมื่อผู้พัฒนาได้รันเครื่องมือสแกนช่องโหว่ซอฟต์แวร์ที่พัฒนาขึ้นเองเทียบกับมาตรฐานอุตสาหกรรม ผลลัพธ์จากสคริปต์ประเมินผลฉบับแรกกลับแสดงตัวเลขที่น่าตกใจ โดยได้ค่าภาพรวมเป็น Precision 0.60, Recall 0.07 และ F1 0.13 ซึ่งตัวเลขเหล่านี้บอกเล่าเรื่องราวที่ชัดเจนเกี่ยวกับประสิทธิภาพในเวลานั้น
สำหรับค่า Precision ที่ระดับ 0.60 หมายความว่าจากสัญญาณเตือนทั้งหมดที่ระบบตรวจพบ มี 60% ที่เป็นบั๊กจริง ส่วนค่า Recall ที่ 0.07 หมายความว่าจากช่องโหว่จริงทั้งหมด 777 รายการใน 4 คลาสที่ระบบครอบคลุม เครื่องมือนี้ค้นพบเพียง 7% เท่านั้น หรือพูดง่ายๆ คือพลาดบั๊กไปถึง 93% และเมื่อนำมารวมกันเป็นค่า F1 จึงเหลือเพียง 0.13 เท่านั้น
โครงการนี้เริ่มต้นจากการสำรวจโลก AI นานหลายเดือน จนเกิดเป็นแนวคิดเครื่องมือสแกนช่องโหว่ที่ใช้กฎ Static Analysis แบบ Deterministic ทำหน้าที่ค้นหา ก่อนจะส่งให้ LLM ช่วยตัดสินใจว่าเป็นบั๊กจริงหรือสัญญาณเตือนที่ผิดพลาด โดยใช้ชุดทดสอบมาตรฐานอย่าง OWASP Benchmark ซึ่งมีชุดทดสอบภาษา Java ถึง 2,740 รายการ และเฉพาะใน 4 คลาสที่ระบบรองรับ (SQL injection, command injection, path traversal, XSS) มีกรณีทดสอบรวม 1,478 รายการ แบ่งเป็นช่องโหว่จริง 777 รายการ และตัวล่อให้เกิดการแจ้งเตือนผิดพลาดอีก 701 รายการ
สำหรับผู้ที่เพิ่งเริ่มต้นศึกษาเรื่องนี้ หัวใจสำคัญอยู่ที่คำว่า Source คือจุดที่ข้อมูลภายนอกที่ไม่น่าเชื่อถือเข้าสู่โปรแกรม ส่วน Sink คือจุดที่ข้อมูลดังกล่าวกลายเป็นอันตรายเมื่อถูกนำไปประมวลผล และช่องโหว่คือการที่ข้อมูลไหลจาก Source ไปยัง Sink โดยไม่มีการตรวจสอบความปลอดภัย ซึ่งกระบวนการติดตามข้อมูลนี้เรียกว่า Taint Analysis

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
การเปิดเผยข้อผิดพลาดหรือผลลัพธ์ที่ย่ำแย่ในระยะเริ่มต้นของการพัฒนาซอฟต์แวร์ถือเป็นเรื่องที่พบได้ยากในวงการ เนื่องจากนักพัฒนาส่วนใหญ่มักเลือกที่จะแก้ไขให้เรียบร้อยก่อนเปิดตัวเพื่อให้ดูสมบูรณ์แบบ ทว่าการสร้างความโปร่งใสโดยการแสดงข้อมูลดิบที่แท้จริง ไม่ว่าจะเป็นตัวเลขที่ต่ำหรือความผิดพลาด ช่วยสร้างความน่าเชื่อถือในระยะยาวและสะท้อนกระบวนการทำงานที่เป็นวิทยาศาสตร์ ซึ่งต้องอาศัยการปรับทีละตัวแปรอย่างแม่นยำ
ในความเป็นจริง เวอร์ชันแรกที่นำมาทดสอบนั้นเป็นเพียง Spike หรือเวอร์ชันทดลองขนาดเล็กที่มีรูปแบบ Source เพียงแบบเดียวคือ getParameter เชื่อมต่อไปยัง Sink จำนวนหนึ่ง เพื่อทดสอบว่าโครงสร้างพื้นฐานทั้งหมดสามารถทำงานร่วมกันได้ตั้งแต่ต้นจนจบหรือไม่ ซึ่งปัญหาค่า Recall ต่ำในลักษณะนี้ไม่ได้หมายความว่าแนวคิดล้มเหลว แต่เป็นสัญญาณบ่งบอกว่ารายการ Source แคบเกินไป ซึ่งเป็นสิ่งที่สามารถแก้ไขได้ง่ายกว่าปัญหาเชิงสถาปัตยกรรมระบบ
ทางเลือกแรกที่หลายคนมักทำคือการปกปิดความผิดพลาดและแก้ไขเงียบๆ เพื่อให้ดูเหมือนประสบความสำเร็จในชั่วข้ามคืน แต่เนื่องจากไม่มีกรรมการภายนอกมาตรวจสอบ ความน่าเชื่อถือจึงขึ้นอยู่กับประวัติความโปร่งใสของผู้เขียนเอง การยอมรับและเผยแพร่ตัวเลข 0.07 ออกมาก่อน จึงเป็นรากฐานสำคัญก่อนที่จะนำไปเปรียบเทียบกับเครื่องมือชื่อดังอื่นๆ อย่าง Semgrep หรือ CodeQL ในอนาคต
ส่วนทางเลือกที่สองที่ควรหลีกเลี่ยงคือการเพิ่มกฎเกณฑ์เข้าไปอย่างไร้ทิศทางเพียงเพื่อดันตัวเลข Recall ให้สูงขึ้น ซึ่งจะทำลายค่า Precision และทำให้ไม่สามารถตรวจสอบได้ว่าการเปลี่ยนแปลงครั้งใดส่งผลอย่างไร สิ่งที่ผู้พัฒนาเลือกทำจึงเป็นการอ่านโค้ดต้นฉบับของชุดทดสอบ ตรวจสอบความถี่ของการใช้งานอินพุตจริง จัดลำดับความสำคัญ และทำการวัดผลใหม่อย่างรอบคอบทีละขั้นตอน
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น