Module 25 Security 5 labs

DevSecOps Fundamentals: SAST, SCA, Secrets & DAST

Tích hợp bảo mật vào pipeline CI/CD từ trái sang phải (Shift-Left Security): phân tích mã tĩnh (SAST), kiểm tra phụ thuộc (SCA), phát hiện secret bị rò rỉ, quét DAST và dựng security gate tự động chặn build không đạt.

Công cụ thực hành Semgrep, Trivy, Grype, Gitleaks, TruffleHog, OWASP ZAP, GitHub Actions
Nền tảng CLI, VS Code, Git, Docker, GitHub Actions, AWS Console
Thời điểm phát hành 23/05/2026
Ngày biên soạn 23/05/2026
Người biên soạn Trần Văn Hòa — Microsoft Certified Trainer (MCT)

Mục tiêu học tập

1. Lý thuyết cốt lõi

1.1. DevSecOps & Shift-Left Security

DevSecOps mở rộng DevOps bằng cách đưa security vào mọi giai đoạn của vòng đời phát triển — từ lúc viết code, commit, build, test đến deploy — thay vì kiểm tra bảo mật chỉ ở cuối (pen test trước release). Nguyên lý Shift-Left: phát hiện lỗ hổng càng sớm, chi phí sửa càng thấp. Một lỗ hổng phát hiện ở giai đoạn design tốn ~1x, ở production tốn ~100x (IBM System Science Institute).

Bốn lớp kiểm soát bảo mật trong pipeline

  • SAST (Static Application Security Testing) — phân tích mã nguồn tĩnh, không cần chạy app. Công cụ: Semgrep, SonarQube, CodeQL.
  • SCA (Software Composition Analysis) — kiểm tra thư viện/dependency có CVE. Công cụ: Trivy, Grype, Dependabot, OWASP Dependency-Check.
  • Secret Scanning — phát hiện API key, password, token bị commit nhầm. Công cụ: Gitleaks, TruffleHog, GitHub Secret Scanning.
  • DAST (Dynamic Application Security Testing) — tấn công ứng dụng đang chạy để tìm lỗ hổng runtime. Công cụ: OWASP ZAP, Burp Suite.

1.2. SAST — Phân tích mã tĩnh

SAST đọc AST (Abstract Syntax Tree) hoặc bytecode để tìm pattern nguy hiểm: SQL injection, XSS, hardcoded credential, insecure deserialization, path traversal… Semgrep nổi bật nhờ rule syntax đơn giản (YAML), hỗ trợ 30+ ngôn ngữ, có registry rule community miễn phí. SonarQube phù hợp enterprise với dashboard, quality gate và CI integration. CodeQL (GitHub) mạnh cho phân tích dataflow phức tạp.

Giới hạn: SAST có false positive cao; cần tune rule theo ngữ cảnh dự án. Không phát hiện được lỗ hổng phụ thuộc runtime (dùng DAST) hay lỗ hổng thư viện bên thứ 3 (dùng SCA).

1.3. SCA — Kiểm tra phụ thuộc

Mã nguồn hiện đại dựa vào 70–90% thư viện bên ngoài. SCA đọc package.json, requirements.txt, go.sum, pom.xml… so sánh với cơ sở dữ liệu CVE (NVD, OSV, GitHub Advisory). Trivy (Aqua Security) đa năng: scan filesystem, Git repo, container image, Kubernetes manifest. Grype (Anchore) chuyên container và SBOM. Dependabot tích hợp sẵn GitHub, tự tạo PR cập nhật dependency.

Công cụScan targetĐiểm mạnh
TrivyImage, FS, repo, SBOM, configĐa năng, nhanh, offline DB
GrypeImage, SBOM (CycloneDX/SPDX)Tích hợp Syft tốt
DependabotRepo GitHub (manifest)Auto PR, zero config

1.4. Secret Scanning

Secret bị commit vào Git là nguyên nhân phổ biến nhất của data breach (GitHub 2023 State of Octoverse: 10+ triệu secret bị phát hiện/năm). Gitleaks quét toàn bộ git history bằng regex + entropy analysis, hỗ trợ pre-commit hook. TruffleHog (Truffle Security) dùng ML để giảm false positive, tích hợp GitHub Actions. Chiến lược: (1) chặn tại pre-commit, (2) quét lịch sử khi onboard repo mới, (3) rotate secret nếu phát hiện.

1.5. DAST — Kiểm tra động

OWASP ZAP (Zed Attack Proxy) là DAST mã nguồn mở nổi tiếng nhất. Hai chế độ trong CI: Baseline Scan (passive — chỉ spider, không tấn công, phù hợp staging) và Full Scan (active — attack simulation, chỉ dùng với môi trường được phép). ZAP Docker image ghcr.io/zaproxy/zaproxy cho phép chạy headless trong pipeline. Kết quả xuất HTML/JSON/XML report.

1.6. Security Gate trong CI/CD

Security gate là bước pipeline tự động chặn build/deploy nếu vi phạm policy: CRITICAL CVE > 0, hardcoded secret, SAST high severity findings. Triển khai qua: --exit-code 1 trong Trivy/Semgrep khi vượt threshold; OPA policy trong Conftest; quality gate trong SonarQube. Nguyên tắc: fail fast, fail loud — thông báo rõ nguyên nhân để developer sửa nhanh.

2. Thực hành (Labs)

LAB-121

SAST với Semgrep — phân tích mã nguồn Python

CLI · Semgrep · Git

🎯 Mục tiêu: Cài Semgrep, quét mã Python có lỗ hổng mẫu (SQL injection, hardcoded password), đọc report và fix.

🧰 Công cụ / nền tảng: Python 3.8+, pip, Semgrep CLI, VS Code, Git.

📦 Chuẩn bị: WSL2 hoặc Linux; Python + pip đã cài. Tài khoản GitHub (optional, cho CI).

▶️ Các bước (CLI):

# 1. Cài Semgrep
pip install semgrep

# 2. Tạo repo lab
mkdir devsecops-m25 && cd devsecops-m25
git init

# 3. Tạo file Python có lỗ hổng mẫu (intentionally vulnerable — dùng để học SAST)
cat > vuln_app.py << 'EOF'
import sqlite3

# Vulnerability 1: SQL injection — nối chuỗi trực tiếp vào query
def get_user(user_id):
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()
    query = "SELECT * FROM users WHERE id = " + user_id   # BAD
    cursor.execute(query)
    return cursor.fetchall()

# Vulnerability 2: Hardcoded credential
DB_PASSWORD = "SuperSecret123!"

# Vulnerability 3: subprocess với shell=True và input chưa được validate
import subprocess
def run_report(report_name):
    # BAD: shell=True kết hợp input người dùng
    subprocess.run("generate-report " + report_name, shell=True)
EOF

# 4. Chạy Semgrep với ruleset chuẩn cộng đồng
semgrep --config=p/python --config=p/secrets vuln_app.py

# 5. Xuất report JSON
semgrep --config=p/python --config=p/secrets vuln_app.py \
    --json --output semgrep-report.json

# 6. Đọc tóm tắt findings
python3 -c "
import json
with open('semgrep-report.json') as f:
    r = json.load(f)
findings = r.get('results', [])
print(f'Total findings: {len(findings)}')
for fi in findings:
    sev = fi['extra']['severity']
    rule = fi['check_id']
    line = fi['start']['line']
    print(f'  [{sev}] {rule} @ line {line}')
"

# 7. Viết lại đúng bằng parameterized query (an toàn)
cat > fixed_app.py << 'EOF'
import sqlite3, subprocess, shlex

def get_user(user_id):
    conn = sqlite3.connect("users.db")
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))  # SAFE
    return cursor.fetchall()

def run_report(report_name):
    # SAFE: danh sách args, không dùng shell=True
    subprocess.run(["generate-report", shlex.quote(report_name)], shell=False)
EOF

# 8. Xác nhận fixed_app.py qua sạch
semgrep --config=p/python fixed_app.py
echo "Semgrep exit code: $?"

✅ Kết quả mong đợi: Scan vuln_app.py phát hiện ≥ 3 findings (SQL injection, hardcoded secret, subprocess với shell=True). Scan fixed_app.py trả về 0 finding. File semgrep-report.json có field results với danh sách lỗi.

🧹 Cleanup: cd .. && rm -rf devsecops-m25 hoặc giữ lại cho LAB-122/123.

LAB-122

SCA với Trivy & Grype — quét dependency và container image

CLI · Trivy · Grype · Docker

🎯 Mục tiêu: Quét requirements.txt và container image tìm CVE, phân loại theo severity, cấu hình exit-code cho security gate.

🧰 Công cụ / nền tảng: Trivy CLI, Grype CLI, Docker, Linux/WSL2.

📦 Chuẩn bị:

# Cài Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
    | sh -s -- -b /usr/local/bin
trivy --version

# Cài Grype
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh \
    | sh -s -- -b /usr/local/bin
grype version

▶️ Các bước (CLI):

# 1. Tạo requirements.txt với các dependency cũ có CVE đã biết
mkdir sca-lab && cd sca-lab
cat > requirements.txt << 'EOF'
flask==0.12.2
requests==2.18.0
Pillow==8.0.0
django==2.0.0
cryptography==2.6.0
EOF

# 2. Scan filesystem — hiển thị table
trivy fs . --severity CRITICAL,HIGH

# 3. Xuất report text chi tiết
trivy fs . --severity CRITICAL,HIGH,MEDIUM \
    --format table --output trivy-fs-report.txt
cat trivy-fs-report.txt

# 4. Xuất JSON (dùng cho automation / dashboards)
trivy fs . --format json --output trivy-report.json
python3 -c "
import json
with open('trivy-report.json') as f:
    data = json.load(f)
results = data.get('Results', [])
total = sum(len(r.get('Vulnerabilities') or []) for r in results)
print(f'Total vulnerabilities: {total}')
for r in results:
    vulns = r.get('Vulnerabilities') or []
    crits = [v for v in vulns if v.get('Severity') == 'CRITICAL']
    if crits:
        print(f'  {r[\"Target\"]}: {len(crits)} CRITICAL')
        for v in crits[:3]:
            print(f'    - {v[\"VulnerabilityID\"]} in {v[\"PkgName\"]} {v[\"InstalledVersion\"]}')
"

# 5. Scan container image (image Python cũ chứa nhiều CVE)
docker pull python:3.8-slim
trivy image --severity CRITICAL,HIGH python:3.8-slim | head -60

# 6. Grype scan — so sánh kết quả với Trivy
grype python:3.8-slim --scope all-layers 2>/dev/null | head -40

# 7. Security gate: exit-code 1 nếu có CRITICAL
trivy fs . --exit-code 1 --severity CRITICAL --quiet
echo "Security gate exit code: $?"
# 0 = pass, 1 = fail (có CRITICAL)

# 8. Fix: update sang phiên bản mới hơn
cat > requirements-updated.txt << 'EOF'
flask==3.0.3
requests==2.31.0
Pillow==10.3.0
django==4.2.13
cryptography==42.0.5
EOF
trivy fs requirements-updated.txt --severity CRITICAL,HIGH --exit-code 1
echo "After update exit code: $?"

✅ Kết quả mong đợi: trivy fs . báo ≥ 5 CRITICAL/HIGH CVE. python:3.8-slim có nhiều OS-level CVE. Sau update requirements-updated.txt, số CRITICAL giảm rõ rệt. --exit-code 1 trả về 1 khi có CRITICAL (dùng để fail CI job).

🧹 Cleanup: docker rmi python:3.8-slim; cd .. && rm -rf sca-lab.

LAB-123

Secret Scanning với Gitleaks & TruffleHog

CLI · Gitleaks · TruffleHog · Git

🎯 Mục tiêu: Phát hiện secret bị chôn vùi trong git history, cài pre-commit hook ngăn commit mới chứa secret, thực hành quy trình remediation.

🧰 Công cụ / nền tảng: Gitleaks v8, TruffleHog v3, git-filter-repo, Git.

📦 Chuẩn bị:

# Cài Gitleaks v8
curl -sSfL \
  https://github.com/gitleaks/gitleaks/releases/download/v8.18.4/gitleaks_8.18.4_linux_x64.tar.gz \
  | tar xz -C /usr/local/bin gitleaks
gitleaks version

# Cài TruffleHog v3
curl -sSfL \
  https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
  | sh -s -- -b /usr/local/bin
trufflehog --version

▶️ Các bước (CLI):

# 1. Giả lập repo có secret bị commit (môi trường học tập)
mkdir secret-lab && cd secret-lab
git init
git config user.email "[email protected]"
git config user.name "Lab Student"

# 2. Commit vô tình chứa credential (fake keys — chỉ để demo Gitleaks)
cat > config.env << 'EOF'
DATABASE_URL=postgresql://admin:[email protected]:5432/appdb
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
STRIPE_SECRET_KEY=sk_live_4eC39HqLyjWDarjtT1zdp7dc
GITHUB_TOKEN=ghp_16C7e42F292c6912E7710c838347Ae298d313
EOF
git add config.env
git commit -m "initial config"

# 3. Cố xóa nhưng sai cách (secret vẫn còn trong history!)
cat > config.env << 'EOF'
# All secrets moved to environment variables
# See .env.example for required keys
EOF
git add config.env
git commit -m "remove secrets from file"

# 4. Gitleaks phát hiện trong toàn bộ git history
gitleaks detect --source . --log-opts="HEAD"

# 5. Gitleaks report chi tiết dạng JSON
gitleaks detect --source . \
    --report-format json \
    --report-path gitleaks-report.json
python3 -c "
import json
with open('gitleaks-report.json') as f:
    findings = json.load(f)
print(f'Secrets found in history: {len(findings)}')
for item in findings:
    print(f'  [{item.get(\"RuleID\")}] {item.get(\"Description\")} @ commit {item.get(\"Commit\",\"\")[:8]}')
"

# 6. TruffleHog quét git history (verifies active credentials)
trufflehog git file://. --no-update 2>/dev/null | head -40

# 7. Cài pre-commit hook với Gitleaks (ngăn commit mới)
cat > .gitleaks.toml << 'EOF'
[extend]
useDefault = true

[[rules]]
description = "Lab: Internal DB URL"
id = "internal-db-url"
regex = '''prod-db\.internal'''
tags = ["custom"]
EOF

cat > .git/hooks/pre-commit << 'HOOKEOF'
#!/bin/bash
echo "[security] Running Gitleaks secret scan..."
gitleaks protect --staged --config=.gitleaks.toml -v
if [ $? -ne 0 ]; then
    echo ""
    echo "BLOCKED: Secret detected in staged changes."
    echo "Remove secrets and use environment variables instead."
    exit 1
fi
HOOKEOF
chmod +x .git/hooks/pre-commit

# 8. Kiểm tra hook hoạt động — thử commit secret mới
echo 'SLACK_TOKEN=xoxb-123456789012-1234567890123-abcDEFghiJKLmnoPQRstu' >> config.env
git add config.env
git commit -m "oops add token"
# Phải bị chặn: exit code 1 + message BLOCKED

# 9. Remediation đúng cách: rewrite history
pip install git-filter-repo
# Xóa file config.env khỏi toàn bộ history
git filter-repo --path config.env --invert-paths --force
git log --oneline   # config.env không còn trong bất kỳ commit nào
# Sau đó: force push + thông báo tất cả team pull lại

✅ Kết quả mong đợi: Gitleaks báo ≥ 5 secret trong history kể cả sau khi đã "xóa" bằng commit mới. TruffleHog xác nhận thêm. Pre-commit hook chặn commit ở bước 8 với thông báo BLOCKED. Sau git filter-repo, git log --all -- config.env trả về rỗng.

🧹 Cleanup: cd .. && rm -rf secret-lab. Quan trọng: Trong thực tế, sau khi phát hiện leak → revoke & rotate credential ngay lập tức, không chờ.

LAB-124

DAST với OWASP ZAP — baseline scan ứng dụng web

CLI · Docker · OWASP ZAP

🎯 Mục tiêu: Chạy OWASP ZAP baseline scan (passive) lên ứng dụng web mẫu, phân tích report HTML/JSON, hiểu phân loại WARN/FAIL.

🧰 Công cụ / nền tảng: Docker, OWASP ZAP Docker image (ghcr.io/zaproxy/zaproxy:stable).

📦 Chuẩn bị: Docker đã cài và chạy. Pull image: docker pull ghcr.io/zaproxy/zaproxy:stable.

▶️ Các bước (CLI):

# 1. Tạo thư mục nhận report
mkdir -p zap-reports

# 2. Chạy ZAP Baseline Scan lên OWASP Juice Shop (public demo)
#    Baseline = passive only (không tấn công, an toàn để chạy trên staging)
docker run --rm \
    -v "$(pwd)/zap-reports:/zap/wrk/:rw" \
    ghcr.io/zaproxy/zaproxy:stable \
    zap-baseline.py \
    -t "https://juice-shop.herokuapp.com" \
    -r zap-report.html \
    -J zap-report.json \
    -l WARN \
    -I
# -l WARN: log level WARN trở lên
# -I: ignore warnings (không fail job, chỉ report)

# 3. Xem tóm tắt alerts từ JSON
python3 << 'PYEOF'
import json, os
report_path = "zap-reports/zap-report.json"
if not os.path.exists(report_path):
    print("Report not found, check Docker volume mount")
    exit(1)
with open(report_path) as f:
    data = json.load(f)
sites = data.get("site", [])
if sites:
    alerts = sites[0].get("alerts", [])
    print(f"Total alert types: {len(alerts)}")
    for a in sorted(alerts, key=lambda x: int(x.get("riskcode","0")), reverse=True):
        risk = a.get("riskdesc", "?")
        name = a.get("alert", "?")
        count = a.get("count", 0)
        print(f"  [{risk}] {name} (instances: {count})")
PYEOF

# 4. Mở report HTML
echo "HTML report: $(pwd)/zap-reports/zap-report.html"
# Trên Windows/WSL: explorer.exe zap-reports/zap-report.html

# 5. Chạy với policy FAIL — exit non-zero nếu có alert ở level FAIL
docker run --rm \
    -v "$(pwd)/zap-reports:/zap/wrk/:rw" \
    ghcr.io/zaproxy/zaproxy:stable \
    zap-baseline.py \
    -t "https://juice-shop.herokuapp.com" \
    -r zap-fail-report.html \
    -l FAIL
echo "ZAP exit code (FAIL policy): $?"

# 6. Scan ứng dụng local (DVWA trong Docker)
docker network create zap-net
docker run -d --name dvwa --network zap-net \
    -p 8080:80 vulnerables/web-dvwa
sleep 15   # Chờ DB init

docker run --rm --network zap-net \
    -v "$(pwd)/zap-reports:/zap/wrk/:rw" \
    ghcr.io/zaproxy/zaproxy:stable \
    zap-baseline.py \
    -t "http://dvwa" \
    -r zap-dvwa-report.html \
    -I

echo "DVWA report: $(pwd)/zap-reports/zap-dvwa-report.html"

✅ Kết quả mong đợi: File zap-reports/zap-report.html tồn tại và mở được trong browser. Python summary liệt kê alerts theo risk (MEDIUM, LOW, INFORMATIONAL). ZAP exit code non-zero khi policy FAIL có alerts. Report DVWA hiển thị nhiều MEDIUM/HIGH hơn Juice Shop.

🧹 Cleanup: docker stop dvwa && docker rm dvwa && docker network rm zap-net && rm -rf zap-reports.

LAB-125

Security Gate trong GitHub Actions pipeline

GitHub Actions · Semgrep · Trivy · Gitleaks

🎯 Mục tiêu: Xây pipeline GitHub Actions tích hợp 3 security scan, cấu hình security gate chặn merge khi CRITICAL CVE hoặc secret bị phát hiện.

🧰 Công cụ / nền tảng: GitHub repo, GitHub Actions, Semgrep Action, Trivy Action, Gitleaks Action.

📦 Chuẩn bị: Repo GitHub có code Python và requirements.txt. GitHub Actions đã bật.

▶️ Các bước:

# 1. Tạo workflow file
mkdir -p .github/workflows

cat > .github/workflows/security-gate.yml << 'EOF'
name: Security Gate

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  # ── GATE 1: Secret Scanning ──────────────────────────────────
  secret-scan:
    name: Secret Scan (Gitleaks)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0     # Full history để scan toàn bộ commits
      - uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        # Job tự động fail nếu phát hiện secret

  # ── GATE 2: SAST ─────────────────────────────────────────────
  sast:
    name: SAST (Semgrep)
    runs-on: ubuntu-latest
    container:
      image: semgrep/semgrep
    steps:
      - uses: actions/checkout@v4
      - name: Run Semgrep
        run: |
          semgrep ci \
            --config=p/python \
            --config=p/secrets \
            --config=p/owasp-top-ten \
            --severity ERROR \
            --error
        # --error: exit 1 nếu có finding severity ERROR hoặc cao hơn

  # ── GATE 3: SCA + Container scan ─────────────────────────────
  sca:
    name: SCA (Trivy)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Scan dependencies (CRITICAL/HIGH → fail)
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: fs
          scan-ref: .
          severity: CRITICAL,HIGH
          exit-code: '1'
          format: table

      - name: Scan IaC/config files (warn only)
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: config
          scan-ref: .
          exit-code: '0'
          format: table

      - name: Upload JSON report as artifact
        if: always()
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: fs
          scan-ref: .
          format: json
          output: trivy-results.json

      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: trivy-security-report
          path: trivy-results.json
          retention-days: 30
EOF

# 2. Cấu hình Branch Protection qua gh CLI
#    (yêu cầu repo owner hoặc admin token)
gh api \
  --method PUT \
  "repos/{owner}/{repo}/branches/main/protection" \
  -f 'required_status_checks[strict]=true' \
  -f 'required_status_checks[contexts][]=Secret Scan (Gitleaks)' \
  -f 'required_status_checks[contexts][]=SAST (Semgrep)' \
  -f 'required_status_checks[contexts][]=SCA (Trivy)' \
  -f 'enforce_admins=false' \
  -f 'restrictions=null' \
  --silent

# 3. Commit và push để trigger pipeline
git add .github/
git commit -m "feat: add security gate pipeline (SAST+SCA+secret scan)"
git push origin main

# 4. Theo dõi pipeline
gh run list --limit 5
gh run watch   # Live stream logs với màu sắc

# 5. Kiểm tra kết quả từng job
RUN_ID=$(gh run list --limit 1 --json databaseId -q '.[0].databaseId')
gh run view $RUN_ID --log | grep -E "(CRITICAL|ERROR|secret|PASS|FAIL)"

✅ Kết quả mong đợi: GitHub Actions hiển thị 3 job riêng biệt. Job sca fail nếu requirements.txt có CRITICAL CVE. Branch protection chặn merge PR khi bất kỳ gate fail. Artifact trivy-security-report xuất hiện trong mỗi run. gh run list hiển thị status failure / success rõ ràng.

🧹 Cleanup: Giữ workflow như portfolio artifact. Tắt branch protection nếu cần: gh api --method DELETE "repos/{owner}/{repo}/branches/main/protection".

3. Tình huống doanh nghiệp thực tế

Bối cảnh

Một công ty fintech phát hiện AWS Access Key bị commit lên GitHub public repo trong quá trình audit bảo mật định kỳ. Key đã active 3 tuần. Cùng lúc, pentest phát hiện SQLi trên API backend do dùng thư viện ORM phiên bản cũ có known CVE CVSS 9.8.

Cách xử lý (DevSecOps)

  • Ngay lập tức (0–2 giờ): Revoke AWS key bị lộ; kiểm tra CloudTrail xem key đã bị exploit chưa; rotate tất cả credential liên quan (DB, 3rd party API).
  • Ngắn hạn (24–72 giờ): Cài Gitleaks pre-commit hook trên tất cả repo; bật GitHub Secret Scanning + Push Protection; chạy TruffleHog quét toàn bộ git history tất cả repo.
  • Xử lý CVE: Trivy scan toàn bộ container images → tạo backlog CVE theo CVSS score → patch CRITICAL trong 48h SLA, HIGH trong 1 tuần, Medium trong 1 sprint.
  • Pipeline: Thêm security gate (Semgrep + Trivy + Gitleaks) vào CI; fail build khi CRITICAL CVE; thêm break-glass process với approval workflow cho emergency patch.
  • Dài hạn: 10% sprint capacity cho security debt; thêm MTTD (Mean Time To Detect) và MTTR security vào DORA dashboard; tổ chức blameless postmortem.

📚 Nguồn tham khảo

Module 24: Database Ops Module 26: Supply Chain Security
Zalo