Hari 9: Semgrep SAST di CI, Pipeline Gagal Karena Kode
4 min read

Hari 9: Semgrep SAST di CI, Pipeline Gagal Karena Kode

Hari kesembilan 60 hari DevSecOps! Masukkin Semgrep ke CI pipeline sebagai SAST quality gate — build otomatis gagal kalau ada insecure pattern di kode.

devsecops
semgrep
sast
ci-cd
github-actions
quality-gate
60-days-challenge
Share

Dari Scan Lokal ke Quality Gate Otomatis

Kemarin Semgrep di-scan lokal dan nemuin 2 masalah di kode kita. Tapi sama kayak Gitleaks dan Trivy di hari-hari sebelumnya — kalau cuma jalanin manual, ada kemungkinan developer lupa. Hari ini kita masukkin Semgrep ke CI pipeline biar setiap push otomatis di-scan, dan pipeline gagal kalau ada insecure pattern di kode.

Ini langkah berikutnya dari shift-left security: bukan cuma nge-laporkan masalah, tapi juga nge-blok PR kalau ada kode yang gak aman.

Job Baru di Pipeline: SAST Scan

Pipeline sekarang punya 4 job paralel:

sast-scan:
  name: SAST Scan (Semgrep)
  runs-on: ubuntu-latest
  steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Run Semgrep
      uses: semgrep/semgrep-action@v1
      with:
        config: >-
          p/golang
          p/owasp-top-ten
          .semgrep.yml

Beberapa keputusan desain:

  • semgrep/semgrep-action@v1 — action resmi dari Semgrep, gratis untuk public repo. Gak butuh SEMGREP_APP_TOKEN buat scan dasar
  • Config: p/golang + p/owasp-top-ten + .semgrep.yml — built-in rules + OWASP Top 10 + custom rules project kita
  • semgrep-action otomatis gagalkan pipeline kalau ada findings — beda sama Trivy yang perlu exit-code: 1, Semgrep langsung exit code 1 kalau ada blocking findings

Awalnya kita juga nyoba upload SARIF ke GitHub Security tab pakai codeql-action/upload-sarif. Tapi ternyata semgrep-action gak generate file SARIF kalau dia gagal (ada findings). Jadi step upload-nya error karena file gak ada. Akhirnya kita hapus SARIF upload dulu — quality gate-nya lebih penting daripada integrasi GitHub Security tab.

Pipeline Sekarang: 4 Lapis Pertahanan

Job Tool Fungsi Status
Build & Test Go 1.26 Build dan unit test ✅ Hijau
Secret Scan Gitleaks Cek secret yang bocor ✅ Hijau
SCA Scan Trivy Cek CVE di dependensi ✅ Hijau (0 CVE setelah remediasi)
SAST Scan Semgrep Cek insecure pattern di kode ❌ Merah (2 findings)

Pipeline sekarang merah karena Semgrep nemuin 2 findings yang sengaja kita taruh di Day 8: MD5 hashing dan HTTP server tanpa TLS.

2 Blocking Findings

❌ no-md5-usage (ERROR) — pkg/crypto/hash.go:11
   MD5 is cryptographically broken. Use SHA-256 or bcrypt for password hashing.

❌ no-http-listen-without-tls (WARNING) — cmd/api/main.go:80
   HTTP server without TLS detected. Use http.ListenAndServeTLS() for production.

Ini contoh yang bagus dari quality gate — kode yang gak aman gak bisa lolos ke main branch. Kalau ada developer yang committer kode pakai MD5, pipeline langsung gagal.

Pelajaran dari SARIF Upload Error

Dalam proses integrasi, kita nemuin 3 masalah:

Masalah Solusi
semgrep-action gak generate SARIF kalau gagal Hapus step upload SARIF dulu — quality gate lebih penting
Workflow butuh security-events: write permission Tambah permissions di workflow file
codeql-action@v3 deprecated Upgrade ke @v4

Keputusan: quality gate lebih penting daripada SARIF upload. Pipeline harus gagal kalau ada findings — itu tujuan utama. SARIF upload bisa ditambahkan nanti setelah semua findings di-remediasi.

Lesson Learned

1. SAST quality gate itu nge-blok kode yang gak aman, bukan cuma nge-laporkan. Berbeda sama scan lokal yang hasilnya cuma report, SAST di CI bikin pipeline gagal. Developer gak bisa merge kalau ada insecure pattern.

2. semgrep-action gratis untuk public repo. Gak butuh SEMGREP_APP_TOKEN buat scan dasar. Ini beda sama gitleaks-action yang butuh lisensi berbayar. Tapi kalau mau integrasi sama Semgrep Cloud dan dashboard, baru butuh token.

3. SARIF upload gak selalu jalan kalau tool-nya gagal. semgrep-action gak generate file SARIF kalau ada findings yang bikin dia exit code 1. Jadi if: always() bukan jaminan file-nya ada — beda sama Trivy yang selalu generate JSON report.

4. Config bisa combine multiple sources. Kita pake 3 sumber sekaligus: p/golang (built-in), p/owasp-top-ten (OWASP), dan .semgrep.yml (custom). Semuanya jalan barengan tanpa konflik.

5. Pipeline makin lengkap = pertahanan makin kuat. Dari cuma build+test di Day 2, sekarang jadi 4 lapis: build, secret scan, SCA, dan SAST. Setiap lapis nge-blok jenis masalah yang berbeda.

Kesimpulan

Pipeline kita sekarang punya 4 lapis pertahanan: build/test, secret scanning, SCA scanning, dan SAST scanning. Kalau ada kode yang gak aman (MD5, HTTP tanpa TLS, dll), pipeline langsung gagal dan PR gak bisa di-merge.

SARIF upload ke GitHub Security tab sementara dihapus karena gak compatible dengan quality gate — semgrep-action gak generate SARIF saat gagal. Ini trade-off yang rasional: lebih penting nge-blok kode yang gak aman daripada punya fancy dashboard.

Yang penting dari hari ini: quality gate SAST bekerja — pipeline merah kalau ada findings, dan hijau kalau semua aman. Di Day 10 nanti kita fix kedua findings ini (MD5 → SHA-256, pertimbangkan TLS) dan pipeline bakal hijau lagi.

Repo: github.com/stayrelevantid/chalange-devsecops

Enjoyed this article? Share it!

Share

Diskusi & Komentar

Artikel Terkait