Gitlab-ci กล้วยๆ: หาช่องโหว่ Dependency ให้แอพเราด้วย Trivy
ในการพัฒนาแอพพลิเคชั่นยังไงเราก็จำเป็นต้องใช้งาน Dependency ข้างนอกมาช่วยทำให้ระบบเราทำงานได้ดีขึ้นในหลายๆ เรื่อง แล้วเราจะมั่นใจได้ยังไงว่า Dependency ที่เราเรียกมาใช้นั้น ไม่มีช่องโหว่ (Vulnerability) ที่อาจทำให้ผู้ไม่ประสงค์เข้ามาโจมตี (Hacker) แอพพลิเคชั่นเราผ่านช่องโหว่นั้นได้
ผมเลยอยากแนะนำเครื่องมือหนึ่งที่ใช้อยู่ประจำและเชื่อถือได้ในการให้มันแสกนหาช่องโหว่ต่างๆ ให้แอพพลิเคชั่นสม่ำเสมอ นั้นคือ...
Trivy คืออะไร
เครื่องมือที่ไว้ใช้แสกนหาช่องโหว่ต่างๆ ในระบบ และรายงานออกมาให้เห็นได้อย่างชัดเจนว่า Dependency ตัวไหนพบเจอระดับความร้ายแรงแค่ไหน ซึ่งรองรับการแสกนได้ตั้งแต่
- Container Image
- Filesystem
- Git Repository (remote)
- Virtual Machine Image
- Kubernetes
- AWS
และรองรับการแสกน packages ของภาษาต่างๆ ได้แก่
- PHP
- Python
- Ruby
- Node.js
- Java
- Go
- Rust
- .NET
- C/C++
- Dart
- Elixir
- Swift
ติดตั้ง Trivy ได้ยังไง?
Ubuntu
$ sudo apt-get install wget apt-transport-https gnupg lsb-release
$ wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
$ echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
$ sudo apt-get update
$ sudo apt-get install trivy
Homebrew (osx)
$ brew install trivy
วิธีใช้งาน Trivy
เนื่องจาก Trivy รองรับการแสกนหลายรูปแบบมาก ในบทความนี้จะสอนแค่เฉพาะการนำมาแสกนหาช่องโหว่ให้กับ Dependency
$ trivy fs ./ --scanners vuln --severity MEDIUM,HIGH,CRITICAL
fs
ระบุว่าให้แสกน Path ไหน—scanners vuln
ค้นหาในรูปแบบ Vulnerability--severity
เป็นการกำหนดระดับความปลอดภัยของช่องโหว่ที่จะให้แสดงผลออกมา รองรับค่าคือ LOW,MEDIUM,HIGH,CRITICAL
เราก็จะได้ผลลัพธ์ออกมาตามรูปบน
Trivy + Gitlab-ci
เราสามารถนำมาใช้คู่กับ gitlab-ci ได้เพื่อให้มันทำการแสกนหาช่องโหว่ให้กับแอพพลิเคชั่นเราทุกครั้งที่มีการ Merge code เข้ามา
รูปแบบไฟล์ gitlab-ci.yml
จะได้แบบนี้
dependency_check:
stage: scan
image:
name: alpine:latest
entrypoint: [""]
before_script:
- apk add --update curl
- export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
- curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v$TRIVY_VERSION
script:
- trivy fs ./ --scanners vuln --exit-code 0 --severity LOW --no-progress
- trivy fs ./ --scanners vuln --exit-code 1 --severity MEDIUM,HIGH,CRITICAL --no-progress
allow_failure: true
trivy fs ./ --scanners vuln --exit-code 0 --severity LOW --no-progress
ส่วนนี้ผมแค่อยากให้มันแสดงผลเมื่อเจอช่องโหว่ระดับ LOWtrivy fs ./ --scanners vuln --exit-code 1 --severity MEDIUM,HIGH,CRITICAL --no-progress
ส่วนนี้ถ้ามันเจอช่องโหว่ระดับ MEDIUM,HIGH,CRITICAL มันจะทำการหลุดออกมาจาก pipeline ให้ ทำให้เราทราบได้ทันทีว่ามีช่องโหว่นี้เกิดขึ้นallow_failure: true
ถ้าต้องการให้มันหยุดการทำงาน pipeline ทันทีที่เจอ ก็เอาอันนี้ออก
ตัวอย่างใน Gitlab-ci
บทสรุป
เพียงเท่านี้ทุกครั้งที่มีการ Push code ขึ้นมาใน repo มันก็จะแสกนให้ทุกรอบ ทำให้เรารู้ว่า Dependency ที่นำมาใช้ปลอดภัยแค่ไหน แล้วเราจะจัดการกับมันยังไงต่อไป
Thank: https://aquasecurity.github.io/trivy