Mỗi pipeline production đều cần ba lớp scan tự động. Thiếu một trong ba, bạn sẽ tốn nhiều giờ trong incident retrospective để giải thích "vì sao chúng ta không bắt được sớm hơn?".
Ba lớp tối thiểu — và lý do
| Lớp | Phát hiện | Tool phổ biến |
|---|---|---|
| SAST | Lỗ hổng trong source code (SQLi, XSS, path traversal, insecure deserialization) | Semgrep, CodeQL, SonarQube |
| SCA | CVE trong dependency, license vi phạm | Trivy, Grype, Snyk, Dependency-Track |
| Secret scan | API key, token, private key vô tình commit | Gitleaks, Trufflehog, GitHub secret scanning |
SAST: bắt đầu với Semgrep
Semgrep dễ bật, ruleset open source rộng, syntax viết rule giống code thật. Workflow GitHub Actions tối thiểu:
name: semgrep
on:
pull_request:
push:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
container: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep ci --config=p/owasp-top-ten --baseline-ref=origin/main
Hai mẹo quan trọng:
- Baseline diff scan: chỉ block finding mới trên PR, finding cũ đưa vào backlog có owner. Tránh vỡ build hàng loạt khi mới bật.
- Custom rule: viết 5-10 rule chặn pattern nội bộ (vd: log secret, gọi API nội không qua client wrapper). Đó là thứ tạo ra giá trị riêng.
SCA và SBOM với Trivy/Grype + Syft
Sinh SBOM CycloneDX và scan CVE trong cùng pipeline:
- name: Generate SBOM
uses: anchore/sbom-action@v0
with:
format: cyclonedx-json
output-file: sbom.cdx.json
name: Scan SBOM with Grype uses: anchore/scan-action@v3 with: sbom: sbom.cdx.json fail-build: true severity-cutoff: high
Đẩy SBOM vào OWASP Dependency-Track để theo dõi long-tail: khi CVE mới được công bố, dashboard tự cảnh báo project bị ảnh hưởng. Chính sách SLA tham khảo:
- CRITICAL có fix sẵn: vá trong 7 ngày.
- HIGH có fix sẵn: vá trong 30 ngày.
- MEDIUM/LOW: review hàng quý, accept hoặc vá theo backlog.
Secret scanning: pre-commit + CI + repo-wide
Ba lớp:
- Pre-commit hook với
gitleaks protect: chặn ngay khi developer commit local. - CI scan trên mỗi PR: bắt secret bypass hook hoặc commit từ web UI.
- Repo-wide history scan định kỳ: phát hiện secret cũ còn nằm trong git log.
Khi phát hiện secret bị lộ:
- Bước 1 — Coi như đã lộ: rotate ngay key/token, không phụ thuộc xoá lịch sử.
- Bước 2: audit usage (CloudTrail, Vault audit log) xem có hành vi bất thường.
- Bước 3: dọn lịch sử với BFG hoặc
git filter-reponếu repo public. - Bước 4: thêm rule pre-commit để pattern tương tự không tái diễn.
Quản lý secret đúng cách
Lý tưởng: code không bao giờ chứa secret, ngay cả ciphertext. Lựa chọn:
- Vault / AWS Secrets Manager / Azure Key Vault với dynamic credential cho DB, queue.
- Mozilla SOPS mã hoá secret file checkin git, key trong KMS — phù hợp GitOps.
- OIDC federation giữa GitHub Actions và cloud, bỏ hẳn long-lived access key.
Cảnh báo: alert fatigue
Bật cùng lúc 3 lớp scan trên 100 repo legacy = vài nghìn finding ngày đầu tiên. Hệ quả: không ai xử, ai cũng disable. Chiến lược an toàn:
- Bật baseline mode: chỉ block finding mới.
- Bắt đầu severity cao (CRITICAL/HIGH) trước, hạ thấp dần.
- Một triage owner chuyên dispatch finding về đúng team trong 24h.
- Dashboard MTTR theo severity là KPI duy nhất, không phải số scan đã chạy.
Kết luận
SAST + SCA + Secret scanning là baseline rẻ và hiệu quả nhất bạn có thể bật trong tuần này. Bắt đầu nhỏ — 1 repo, 1 ruleset, 1 pre-commit hook — đo MTTR, mở rộng dần. Sau 3-4 tháng, ba lớp này sẽ chặn được phần lớn loại lỗi cơ bản, cho phép team security tập trung năng lượng vào threat model, supply chain và runtime.



