Belajar Application Security Engineer - SAST & Static Analysis
Episode 7 of 28

Belajar Application Security Engineer - SAST & Static Analysis

Memahami cara kerja SAST dari taint analysis hingga rule engine, menulis rule Semgrep kustom untuk pola berbahaya di codebase tim, membandingkan Semgrep vs CodeQL, dan mengintegrasikan semuanya ke pull request dengan rasio false positive yang tetap manusiawi

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 6 kita mengamankan API, kita mulai fase tooling series ini: SAST (Static Application Security Testing) — analisis kode sumber tanpa menjalankannya untuk menemukan kerentanan. Mengapa SAST jadi tulang punggung AppSec modern? Karena ia satu-satunya teknik yang bisa berjalan di setiap commit, dalam hitungan menit, sebelum kode menyentuh build mana pun. Ini mesin utama shift-left.

Tapi SAST juga punya reputasi bermasalah: false positive berlebihan membuat developer mematikannya. Episode ini mengajarkan cara kerjanya sampai level rule agar kalian bisa menyetir tool-nya, bukan sekadar menjalankan.

Cara Kerja SAST

Ada dua generasi teknologi di balik SAST:

Pattern Matching (Generasi 1)

Tool mencocokkan pola sintaksis berbahaya — mirip grep yang sadar-AST. Cepat, murah, mudah ditulis ulang, tapi buta terhadap aliran data antar file. Contoh klasik yang terlewat: source dari req.body di file A, sink exec() di file B.

Data Flow / Taint Analysis (Generasi 2)

Mesin membangun graf aliran data dan melacak perjalanan source → sink:

Model taint analysis
SOURCE : input tak terpercaya   → req.body, req.query, env eksternal
SINK   : operasi berbahaya      → exec(), db.query(), innerHTML, redirect()
SANITIZER : pembersih di jalur  → parameterized binding, escape, allowlist check

Temuan hanya dilaporkan jika data tercemar mencapai sink tanpa melewati sanitizer. Inilah yang membuat hasilnya jauh lebih relevan — dan inilah inti CodeQL serta mode dataflow Semgrep.

Note

Analogi sederhana: pattern matching adalah detektif yang curiga pada semua orang bertopi hitam; taint analysis adalah detektif yang mengikuti jejak dari rumah korban sampai ke pelaku. Keduanya berguna, tapi yang kedua yang bisa dipercaya untuk kasus kompleks.

Semgrep: SAST yang Developer-Friendly

Semgrep adalah pilihan default saya untuk tim karena rule-nya ditulis dalam sintaks yang nyaris identik dengan bahasa target — tidak perlu belajar DSL baru:

.semgrep/express-taint.yaml — rule kustom
rules:
  - id: express-child-process-user-input
    languages: [javascript, typescript]
    message: User input flows into child_process.exec — potential command injection
    severity: ERROR
    metadata:
      cwe: "CWE-78: OS Command Injection"
      owasp: "A03: Injection"
    mode: taint
    pattern-sources:
      - pattern: $REQ.body
      - pattern: $REQ.query
      - pattern: $REQ.params
    pattern-sinks:
      - pattern: exec($DATA, ...)
      - pattern: $CHILD.exec($DATA, ...)

Jalankan secara lokal — developer bisa memakai tool yang sama persis dengan CI:

Scan dengan ruleset komunitas + rule lokal
semgrep scan --config auto --config .semgrep/ .
semgrep scan --config p/owasp-top-ten --config p/secrets .

Ruleset komunitas (p/owasp-top-ten, p/security-audit, p/typescript) memberi cakupan instan; rule kustom tim menangkap pola spesifik framework internal kalian — misalnya helper DB internal yang ternyata menerima raw query.

CodeQL: Analisis Mendalam ala GitHub

CodeQL memperlakukan kode sebagai database yang bisa di-query. Lebih lambat dan kurva belajarnya lebih tinggi, tetapi kemampuannya lintas-repository dan sangat presisi:

Query CodeQL: eval dengan input HTTP
import javascript
 
from EvalInvocation eval, DataFlow::PathNode src
where
  src.getNode() instanceof ActiveThreatModelSource and
  eval.flowTo(src)
select eval, "User input reaches eval() — risk of RCE."

Kapan pakai yang mana? Praktik umum di industri:

KriteriaSemgrepCodeQL
Kecepatan per PRDetik–menitMenit–puluhan menit
Penulisan rule customSangat mudahButuh latihan QL
Deep interproceduralMode taint baikTerbaik
BiayaOSS gratisGratis di public repo

Banyak organisasi matang memakai keduanya: Semgrep di setiap PR, CodeQL sebagai scan mingguan mendalam.

Integrasi ke Pull Request

Nilai SAST ada di tempat temuan muncul: pull request, bukan dashboard yang tidak pernah dibuka. Pola GitHub Actions minimal:

.github/workflows/sast.yml
name: SAST
on:
  pull_request:
jobs:
  semgrep:
    runs-on: ubuntu-latest
    container:
      image: semgrep/semgrep
    steps:
      - uses: actions/checkout@v4
      - run: semgrep ci --config auto --config .semgrep/
        env:
          SEMGREP_RULES: p/owasp-top-ten p/secrets

Dua prinsip agar integrasinya diterima developer:

  1. Fail hanya pada temuan baru: bandingkan dengan baseline branch utama. Temuan lama masuk backlog, bukan blocker PR.
  2. Hasil sebagai komentar inline: temuan di baris yang bersangkutan dengan penjelasan + saran fix — bukan log mentah di tab Actions.

Tip

Tambahkan Semgrep ke pre-commit hook dengan scope file yang di-stage saja. Menemukan injection saat mengetik jauh lebih murah daripada menemukannya di review PR — itulah shift-left yang sesungguhnya.

Mengelola False Positive

Rasio temuan valid adalah nyawa program SAST. Di bawah ±50% precision, developer mulai menandai semua alert sebagai noise. Strategi pengelolaannya:

  1. Audit setiap rule sebelum aktifkan — jalankan di seluruh codebase dulu, ukur rasio benar/salah.
  2. Suppress yang eksplisit, bukan diam-diam: gunakan komentar inline (// nosemgrep: rule-id) dengan alasan tertulis; suppress tanpa alasan = utang.
  3. Narrowing rule: tambahkan pattern-inside atau kondisi sanitizer agar rule hanya bunyi pada konteks benar-benar berbahaya.
  4. Metrik: pantau dismissal rate per rule tiap bulan — rule yang 90% dibantah harus direvisi atau dipensiunkan.

Common Pitfalls

  • Menyalakan 200 rule sekaligus hari pertama: banjir temuan 3 ribu item → program mati minggu kedua. Mulai 10–20 rule berkualitas.
  • Menganggap SAST = security: SAST buta pada business logic, misconfiguration runtime, dan dependency rentan — itulah kenapa DAST/SCA ada (episode 8–9).
  • Rule generic untuk framework internal: tool publik tidak kenal helper internal kalian; investasikan waktu menulis rule spesifik repo.
  • Skip scanning test files: kode test dieksekusi juga di CI dengan secret asli — scan semuanya, dengan tuning severity.

Penutup

Inti yang harus dibawa pulang:

  • Dua generasi SAST: pattern matching cepat tapi dangkal; taint analysis melacak source→sink dan jauh lebih presisi.
  • Semgrep untuk velocity harian dan rule kustom; CodeQL untuk analisis mendalam berkala.
  • Nilai SAST ada di integrasi PR: fail temuan baru saja, tampilkan inline, baseline temuan lama.
  • Kelola false positive seperti produk: audit rule, suppress eksplisit, metrik dismissal rate.

Di episode 8 kita pindah ke sisi dinamis: DAST & Dynamic Testing — Burp Suite dan OWASP ZAP, crawling aplikasi nyata, authenticated scanning, dan cara membaca hasilnya tanpa salah prioritas. Sampai jumpa di episode 8!

Belajar Application Security Engineer - SAST & Static Analysis | Belajar Application Security Engineer