Gitlab-ci กล้วยๆ: หาช่องโหว่ Dependency ให้แอพเราด้วย Trivy

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 ส่วนนี้ผมแค่อยากให้มันแสดงผลเมื่อเจอช่องโหว่ระดับ LOW
  • trivy 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

Arnon Kijlerdphon

Arnon Kijlerdphon

Choosing to live a plant-based lifestyle for the animals, my health, and the future of our planet.
Bangkok, Thailand