- การคำนึงถึงความปลอดภัยระหว่างเขียนโค้ด Go เป็นงานที่ซับซ้อน
- บทความนี้นำเสนอแนวปฏิบัติที่เป็นรูปธรรมหลายข้อ ซึ่งหากนำไปใช้อย่างต่อเนื่องจะช่วยให้เขียนโค้ดที่แข็งแกร่ง ปลอดภัย และมีประสิทธิภาพสูงได้
อัปเดตเวอร์ชัน Go ให้เป็นปัจจุบันเสมอ
- ต้องคงเวอร์ชัน Go ที่ใช้ในโปรเจ็กต์ให้เป็นเวอร์ชันล่าสุด
- แม้จะไม่ได้ใช้ฟีเจอร์ภาษาใหม่ล่าสุด การอัปเกรดเวอร์ชัน Go ก็ยังช่วยให้ได้รับแพตช์ความปลอดภัยทั้งหมดสำหรับช่องโหว่ที่ค้นพบแล้ว
- Go เวอร์ชันใหม่ยังช่วยรับประกันความเข้ากันได้กับ dependency รุ่นล่าสุด
- สามารถตรวจสอบได้จากเว็บไซต์ประวัติการออกรีลีสของ Go ว่ารีลีสใดแก้ปัญหาความปลอดภัยและ CVE อะไรบ้าง แล้วอัปเดตเป็นเวอร์ชันล่าสุดในไฟล์
go.mod ของโปรเจ็กต์
- หลังอัปเกรดเวอร์ชัน Go แล้ว ควรตรวจสอบว่าไม่มีปัญหาเรื่องความเข้ากันได้และ dependency
- สามารถใช้ตัววิเคราะห์โค้ดแบบสแตติกเพื่อประเมินคุณภาพและความปลอดภัยของโค้ดได้
vet
- วิเคราะห์โค้ด Go ได้ด้วยคำสั่ง
go vet ที่ Go มีมาให้ในตัว
- หากรันคำสั่ง
go vet โดยไม่ส่งอาร์กิวเมนต์ จะทำงานด้วยตัวเลือกเริ่มต้นที่อนุญาตทั้งหมด
- จะสแกนซอร์สโค้ดและรายงานปัญหาที่อาจเกิดขึ้น
- ปัญหาที่พบบ่อยที่สุดได้แก่ ความผิดพลาดเกี่ยวกับ goroutine, ตัวแปรที่ไม่ได้ใช้งาน, และส่วนของโค้ดที่ไม่สามารถเข้าถึงได้
staticcheck
- Staticcheck ซึ่งเป็น linter จาก third party ช่วยค้นหาบั๊ก ตรวจจับปัญหาด้านประสิทธิภาพ และบังคับใช้สไตล์ของภาษา Go
- อธิบายปัญหาที่พบและเสนอแนวทางแก้ไขพร้อมตัวอย่าง
- นอกจากรันใน CI pipeline แล้ว ยังติดตั้งเป็นไฟล์ปฏิบัติการแบบสแตนด์อโลนเพื่อสแกนโค้ดบนเครื่องโลคัลได้
- ตรวจสอบเวอร์ชันที่ติดตั้งและยืนยันว่าพร้อมสำหรับการรันสแกน
- หากรันโดยไม่ส่งอาร์กิวเมนต์ จะเรียกใช้ตัววิเคราะห์โค้ดทั้งหมดโดยค่าเริ่มต้น
- ดูตัวอย่างสิ่งที่สามารถตรวจพบได้ใน GitHub repository ของ NGINX Agent
- ผลการสแกนสามารถแบ่งได้เป็น 3 กลุ่ม ได้แก่ แพ็กเกจ/เมธอด/ฟังก์ชันที่ deprecated, ตัวแปร/ฟิลด์ที่ไม่ได้ใช้งาน, และปัญหาที่เกี่ยวกับคุณภาพโค้ด
golangci-lint
- ติดตั้ง
golangci-lint ได้ด้วยคำสั่ง go install
- ตรวจสอบเวอร์ชันเพื่อยืนยันว่าติดตั้งเรียบร้อยแล้ว
- หากเรียกใช้โดยไม่ส่งอาร์กิวเมนต์ จะรัน linter ทั้งหมด
- ตรวจดูว่ามีคำเตือนและข้อเสนอแนะใดบ้างใน repository
agent ที่โคลนไว้ก่อนหน้านี้
- linter จะระบุไฟล์และบรรทัดที่เกี่ยวข้องได้อย่างแม่นยำ
- ประเมินโค้ดและแก้ไข จากนั้นรัน linter อีกครั้งและรัน unit test ทั้งหมด
- หากการทดสอบผ่าน ก็ commit โค้ดที่อัปเดตแล้วและ push ขึ้นรีโมต
การตรวจจับ Race Condition
- Race condition อาจเกิดขึ้นเมื่อหลาย goroutine พยายามเข้าถึงทรัพยากรเดียวกันพร้อมกัน
- จะถูกตรวจจับเมื่อมีอย่างน้อยหนึ่ง goroutine พยายามแก้ไขทรัพยากรนั้น
- Go รองรับการทดสอบสถานะลักษณะนี้โดยตรงผ่านเครื่องมือ
test ร่วมกับอาร์กิวเมนต์ -race
- ตัวตรวจจับ race จะประเมินเฉพาะโค้ดที่ถูกรันจริง และจะมองข้ามเส้นทางโค้ดที่ไม่ถูกรัน ดังนั้นจึงควรรันตัววิเคราะห์โค้ดแบบสแตติกก่อนเพื่อให้แน่ใจว่าไม่มี dead code
- การรันทดสอบแบบขนานจะเพิ่มโอกาสในการตรวจพบปัญหาที่เกี่ยวข้องกับ concurrency
การสแกนซอร์สโค้ดหาช่องโหว่
govulncheck
- เครื่องมือสำหรับสแกนโค้ดเบสเพื่อหาช่องโหว่ที่ทราบแล้วซึ่งอยู่ในฐานข้อมูล CVEs
- พัฒนาโดยทีม Go และมีฐานข้อมูลเฉพาะด้านช่องโหว่ของ Go เป็นแหล่งข้อมูลให้ตัวสแกน
- ติดตั้งเวอร์ชันล่าสุดแล้วลองใช้งานฟังก์ชันพื้นฐาน
- โคลน repository habit แล้วรันเครื่องมือจากไดเรกทอรีราก
- ไม่พบช่องโหว่
- หากสแกนไฟล์ไบนารี อาจพบช่องโหว่อื่นเพิ่มเติมได้
- อัปเกรดเวอร์ชัน Go ให้ล่าสุด ดึง dependency มาให้ครบ แล้วตรวจสอบว่าซอฟต์แวร์และ dependency ไม่มี CVE
gosec
- ตัววิเคราะห์โค้ดแบบสแตติกที่ช่วยค้นหาการตั้งค่าโค้ดที่ไม่ปลอดภัย
- สามารถรันได้ทั้งบนระบบโลคัลหรือใน CI pipeline ผ่าน GitHub Action
- มีตัวเลือกและรายการกฎสำหรับตั้งค่าการสแกนที่หลากหลาย
- โคลน GitHub repository ที่มีโค้ด Go ที่ต้องการสแกน แล้วเริ่มสแกนจากไดเรกทอรีราก
- ในรายงานการสแกน สามารถดูรายการปัญหาที่อาจเกิดขึ้นซึ่งจัดเรียงตามระดับความรุนแรงและความน่าเชื่อถือได้
- ตรวจสอบ CWE ที่ถูกรายงานและศึกษารายละเอียดเพิ่มเติมเกี่ยวกับจุดอ่อนที่ระบุไว้
Fuzzing
- วิธีสุดท้ายในการตรวจสอบคุณภาพโค้ดและค้นหาช่องโหว่
- เป็นการทดสอบอัตโนมัติแบบเฉพาะทางที่ใช้ code coverage ของการทดสอบเพื่อปรับแต่งข้อมูลนำเข้าแบบสุ่มที่สร้างขึ้น
- มีประโยชน์มากในการค้นหาข้อบกพร่องด้านความปลอดภัยที่อาจเกิดขึ้น เช่น buffer overflow, SQL injection, การโจมตีแบบ DoS, และการโจมตีแบบ XSS
- เนื่องจากมีการสร้างชุดข้อมูลนำเข้าหลายรูปแบบโดยอัตโนมัติ นักพัฒนาจึงไม่จำเป็นต้องคิดชุดข้อมูลอินพุตนับร้อยหรือนับพันแบบด้วยตนเอง
1 ความคิดเห็น
ความเห็นบน Hacker News
govulncheckเป็นเครื่องมือที่ตรวจสอบได้ว่าโค้ดที่มีช่องโหว่นั้นถูกเข้าถึงใช้งานจริงหรือไม่ จึงมีประโยชน์กว่าการตรวจสอบ dependency ของโปรแกรมเพียงอย่างเดียวgo vetและgo test -racegosec