spinny:~/writing $ vim devsecops-shift-left-security-guide.md
1~2Kerentanan yang ditemui semasa menulis kod memerlukan beberapa minit sahaja untuk diperbaiki oleh pembangun perisian. Kerentanan yang sama jika ditangkap di production memerlukan satu sprint penuh. Dan jika penyerang menemuinya terlebih dahulu, kosnya berjuta-juta. Inilah hujah teras di sebalik **shift-left security** - memindahkan pemeriksaan keselamatan seawal mungkin dalam kitaran hayat pembangunan.3~4DevSecOps mengambil idea ini dan mengubahnya menjadi amalan: keselamatan bukan fasa berasingan di penghujung tetapi proses berterusan yang dijalin ke setiap peringkat pembangunan, dari baris kod pertama hingga deployment production.5~6## Kos Keselamatan Lewat7~8Laporan Cost of a Data Breach IBM telah menunjukkan secara konsisten bahawa kos membaiki isu keselamatan meningkat secara eksponen semakin lewat ia ditangkap:9~10| Peringkat | Kos Pembaikan | Masa Pembaikan |11|-------|------------|-------------|12| **IDE / Local Dev** | Minit | Saat hingga minit |13| **Code Review / PR** | Jam | Minit hingga jam |14| **CI/CD Pipeline** | Hari | Jam hingga hari |15| **Staging / QA** | Minggu | Hari |16| **Production** | Bulan | Minggu hingga bulan |17| **Post-breach** | Jutaan ($) | Bulan hingga tahun |18~19Kesimpulannya jelas: setiap peringkat yang anda pindahkan keselamatan lebih awal menjimatkan satu orde magnitud dalam kos dan masa.20~21## Pipeline DevSecOps22~23Pipeline DevSecOps yang matang mengintegrasikan pemeriksaan keselamatan di setiap peringkat:24~25```mermaid26graph LR27 IDE[IDE / Editor] --> PC[Pre-commit Hooks]28 PC --> PR[Pull Request]29 PR --> CI[CI Pipeline]30 CI --> Build[Build / Package]31 Build --> Deploy[Deploy]32 Deploy --> Runtime[Runtime / Production]33~34 IDE -.- S1[SAST\nSecret Detection\nLinting]35 PC -.- S2[Secrets Scan\nFormat Check]36 PR -.- S3[Code Review\nDependency Audit]37 CI -.- S4[SAST\nSCA\nContainer Scan\nSBOM]38 Build -.- S5[Image Signing\nArtifact Verification]39 Deploy -.- S6[Policy Enforcement\nAdmission Control]40 Runtime -.- S7[DAST\nWAF\nMonitoring]41```42~43Mari kita huraikan setiap peringkat dengan alat dan konfigurasi yang konkrit.44~45## Peringkat 1: Keselamatan di IDE46~47Gelung maklum balas terpantas. Tangkap kerentanan sebelum anda menyimpan fail.48~49### Alat yang Disyorkan50~51- **Semgrep**: analisis statik ringan dengan peraturan komuniti untuk kerentanan OWASP52- **Snyk IDE Extension**: pengimbasan kerentanan dependency masa nyata53- **GitLens + GitLeaks**: kesan secrets dalam editor anda54- **ESLint Security Plugins**: `eslint-plugin-security` untuk Node.js, `eslint-plugin-no-unsanitized` untuk DOM XSS55~56### Contoh: Konfigurasi ESLint Security57~58```json59{60 "extends": ["eslint:recommended"],61 "plugins": ["security", "no-unsanitized"],62 "rules": {63 "security/detect-object-injection": "warn",64 "security/detect-non-literal-regexp": "warn",65 "security/detect-unsafe-regex": "error",66 "security/detect-buffer-noassert": "error",67 "security/detect-eval-with-expression": "error",68 "security/detect-no-csrf-before-method-override": "error",69 "security/detect-possible-timing-attacks": "warn",70 "no-unsanitized/method": "error",71 "no-unsanitized/property": "error"72 }73}74```75~76## Peringkat 2: Pre-commit Hooks77~78Barisan pertahanan kedua. Berjalan secara automatik sebelum setiap commit, menghalang kod berbahaya daripada memasuki repositori.79~80### Gitleaks: Tangkap Secrets Sebelum Sampai ke Git81~82Kesalahan keselamatan paling biasa dalam codebase ialah meng-commit secrets - API keys, database passwords, tokens. Sebaik sahaja secret masuk ke git history, ia amat sukar untuk dikeluarkan sepenuhnya (walaupun dengan force pushes, fork dan cache mungkin masih menyimpannya).83~84```yaml85# .pre-commit-config.yaml86repos:87 - repo: https://github.com/gitleaks/gitleaks88 rev: v8.21.089 hooks:90 - id: gitleaks91~92 - repo: https://github.com/semgrep/semgrep93 rev: v1.90.094 hooks:95 - id: semgrep96 args: ['--config', 'auto']97```98~99Pasang dan aktifkan:100~101```bash102pip install pre-commit103pre-commit install104```105~106Kini setiap `git commit` mengimbas secara automatik untuk secrets yang bocor dan kerentanan biasa. Jika sesuatu ditemui, commit akan disekat.107~108### Peraturan Gitleaks Tersuai109~110Anda boleh menambah corak tersuai untuk secrets organisasi anda:111~112```toml113# .gitleaks.toml114title = "Custom Gitleaks Config"115~116[[rules]]117id = "internal-api-key"118description = "Internal API key detected"119regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}'''120tags = ["key", "internal"]121```122~123## Peringkat 3: Keselamatan CI/CD Pipeline124~125Di sinilah kerja berat berlaku. Pipeline CI anda harus menjalankan pelbagai imbasan keselamatan pada setiap pull request.126~127### SAST (Static Application Security Testing)128~129Alat SAST menganalisis kod sumber tanpa melaksanakannya, mencari corak yang menunjukkan kerentanan.130~131```yaml132# .github/workflows/security.yml133name: Security Scan134on:135 pull_request:136 branches: [main]137~138jobs:139 sast:140 name: Static Analysis141 runs-on: ubuntu-latest142 steps:143 - uses: actions/checkout@v4144~145 - name: Run Semgrep146 uses: semgrep/semgrep-action@v1147 with:148 config: >-149 p/owasp-top-ten150 p/typescript151 p/nodejs152 p/react153 generateSarif: true154~155 - name: Upload SARIF156 uses: github/codeql-action/upload-sarif@v3157 with:158 sarif_file: semgrep.sarif159```160~161Set peraturan `p/owasp-top-ten` Semgrep menangkap kerentanan paling biasa: SQL injection, XSS, SSRF, path traversal, insecure deserialization, dan banyak lagi.162~163### SCA (Software Composition Analysis)164~165SCA mengimbas dependency anda untuk kerentanan yang diketahui. Ini amat kritikal - lebih 80% kod aplikasi moden datang dari dependency open-source.166~167```yaml168 dependency-scan:169 name: Dependency Audit170 runs-on: ubuntu-latest171 steps:172 - uses: actions/checkout@v4173~174 - name: Run Snyk175 uses: snyk/actions/node@master176 env:177 SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}178 with:179 args: --severity-threshold=high180~181 - name: npm audit182 run: npm audit --audit-level=high183```184~185### Container Security dengan Trivy186~187Jika anda membina Docker images, mengimbasnya untuk kerentanan adalah penting. **Trivy** ialah container scanner open-source paling popular.188~189```yaml190 container-scan:191 name: Container Security192 runs-on: ubuntu-latest193 steps:194 - uses: actions/checkout@v4195~196 - name: Build image197 run: docker build -t my-app:${{ github.sha }} .198~199 - name: Run Trivy200 uses: aquasecurity/trivy-action@master201 with:202 image-ref: my-app:${{ github.sha }}203 format: 'sarif'204 output: 'trivy-results.sarif'205 severity: 'CRITICAL,HIGH'206 exit-code: '1'207~208 - name: Upload Trivy SARIF209 uses: github/codeql-action/upload-sarif@v3210 with:211 sarif_file: trivy-results.sarif212```213~214### Penjanaan SBOM215~216**Software Bill of Materials (SBOM)** ialah inventori lengkap setiap komponen dalam aplikasi anda. Semakin diperlukan oleh rangka kerja pematuhan dan peraturan kerajaan (US Executive Order on Cybersecurity mewajibkan SBOM untuk perisian persekutuan).217~218```yaml219 sbom:220 name: Generate SBOM221 runs-on: ubuntu-latest222 steps:223 - uses: actions/checkout@v4224~225 - name: Generate SBOM with Syft226 uses: anchore/sbom-action@v0227 with:228 format: spdx-json229 output-file: sbom.spdx.json230~231 - name: Upload SBOM232 uses: actions/upload-artifact@v4233 with:234 name: sbom235 path: sbom.spdx.json236```237~238## Peringkat 4: Docker Images yang Selamat239~240Docker image production harus mengikuti prinsip keistimewaan minimum. Inilah rupa Dockerfile yang diperkukuh:241~242```dockerfile243# Build stage244FROM node:22-alpine AS builder245WORKDIR /app246COPY package.json package-lock.json ./247RUN npm ci248COPY . .249RUN npm run build250~251# Production stage252FROM node:22-alpine AS runner253WORKDIR /app254~255# Install dumb-init before dropping root256RUN apk add --no-cache dumb-init257~258# Don't run as root259RUN addgroup -S app && adduser -S app -G app260~261# Copy only what's needed262COPY --from=builder --chown=app:app /app/dist ./dist263COPY --from=builder --chown=app:app /app/node_modules ./node_modules264COPY --from=builder --chown=app:app /app/package.json ./265~266# Drop to non-root user267USER app268ENTRYPOINT ["dumb-init", "--"]269~270# Health check271HEALTHCHECK --interval=30s --timeout=3s --retries=3 \272 CMD wget -qO- http://localhost:3000/health || exit 1273~274EXPOSE 3000275CMD ["node", "dist/server.js"]276```277~278Amalan utama:279~2801. **Gunakan multi-stage builds**: peringkat builder mempunyai dev dependencies; peringkat runner hanya mempunyai kod production2812. **Jangan jalankan sebagai root**: cipta pengguna bukan root dan bertukar kepadanya2823. **Gunakan Alpine images**: permukaan serangan lebih kecil (lebih sedikit pakej dipasang secara lalai)2834. **Pin versi image**: `node:22-alpine` dan bukannya `node:latest` untuk mengelak serangan rantaian bekalan2845. **Gunakan `npm ci`**: pemasangan deterministik daripada fail kunci, bukan `npm install`285~286## Peringkat 5: Pengurusan Secret287~288Hard-coded secrets ialah punca nombor satu pelanggaran dalam insiden yang disebabkan pembangun perisian.289~290### Apa yang TIDAK Boleh Dilakukan291~292```typescript293// NEVER do this294const API_KEY = "sk-1234567890abcdef";295const DB_PASSWORD = "supersecret123";296~297const client = new Client({298 connectionString: `postgres://admin:${DB_PASSWORD}@db.example.com/prod`299});300```301~302### Apa yang Perlu Dilakukan Sebaliknya303~304```typescript305// Use environment variables306const client = new Client({307 connectionString: process.env.DATABASE_URL308});309~310// Or use a secret manager311import { SecretManagerServiceClient } from '@google-cloud/secret-manager';312~313const client = new SecretManagerServiceClient();314const [version] = await client.accessSecretVersion({315 name: 'projects/my-project/secrets/db-password/versions/latest',316});317const dbPassword = version.payload?.data?.toString();318```319~320### Hierarki Pengurusan Secret321~322```mermaid323graph TD324 A[Secret Manager\nAWS Secrets Manager\nGCP Secret Manager\nHashiCorp Vault] --> B[Best: Rotated, audited, centralized]325 C[Environment Variables\nInjected at deploy time] --> D[Good: Not in code, but static]326 E[.env files\nWith .gitignore] --> F[Acceptable: Local development only]327 G[Hard-coded in source] --> H[NEVER: Instant breach risk]328~329 style A fill:#d4edda330 style C fill:#fff3cd331 style E fill:#ffeeba332 style G fill:#f8d7da333```334~335## OWASP Top 10: Rujukan Pantas336~337Setiap pembangun perisian harus mengetahui OWASP Top 10. Versi ringkas:338~339| # | Kerentanan | Apa Itu | Pencegahan |340|---|--------------|-----------|------------|341| 1 | **Broken Access Control** | Pengguna mengakses sumber yang tidak sepatutnya | Tolak secara lalai, sahkan di sisi pelayan |342| 2 | **Cryptographic Failures** | Penyulitan lemah, data teks biasa | Guna algoritma kuat (AES-256, bcrypt), TLS di mana-mana |343| 3 | **Injection** | SQL, NoSQL, OS command injection | Parameterized queries, pengesahan input |344| 4 | **Insecure Design** | Seni bina yang cacat | Threat modeling, corak reka bentuk selamat |345| 5 | **Security Misconfiguration** | Kelayakan lalai, cloud buckets terbuka | Lalai yang diperkukuh, audit konfigurasi automatik |346| 6 | **Vulnerable Components** | CVE yang diketahui dalam dependency | Imbasan SCA, kemas kini berkala |347| 7 | **Auth Failures** | Kata laluan lemah, sesi rosak | MFA, pengehadan kadar, pengurusan sesi selamat |348| 8 | **Data Integrity Failures** | Kemas kini tidak ditandatangani, CI/CD tidak dipercayai | Tandatangan kod, SBOM, integriti pipeline |349| 9 | **Logging Failures** | Tiada jejak audit | Logging berstruktur, amaran pada anomali |350| 10 | **SSRF** | Server-side request forgery | Senarai putih URL keluar, sahkan input |351~352## Aliran Kerja GitHub Actions Security Lengkap353~354Aliran kerja lengkap dan sedia production yang menggabungkan semua di atas:355~356```yaml357# .github/workflows/security.yml358name: Security Pipeline359on:360 pull_request:361 branches: [main]362 push:363 branches: [main]364~365permissions:366 contents: read367 security-events: write368~369jobs:370 secrets-scan:371 name: Secret Detection372 runs-on: ubuntu-latest373 steps:374 - uses: actions/checkout@v4375 with:376 fetch-depth: 0377 - uses: gitleaks/gitleaks-action@v2378 env:379 GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}380~381 sast:382 name: Static Analysis (SAST)383 runs-on: ubuntu-latest384 steps:385 - uses: actions/checkout@v4386 - uses: semgrep/semgrep-action@v1387 with:388 config: p/owasp-top-ten p/typescript p/nodejs389~390 dependency-audit:391 name: Dependency Scan (SCA)392 runs-on: ubuntu-latest393 steps:394 - uses: actions/checkout@v4395 - uses: actions/setup-node@v4396 with:397 node-version: 22398 - run: npm ci399 - run: npm audit --audit-level=high400 - uses: snyk/actions/node@master401 env:402 SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}403 with:404 args: --severity-threshold=high405 continue-on-error: true406~407 container-scan:408 name: Container Scan409 runs-on: ubuntu-latest410 needs: [sast, dependency-audit]411 steps:412 - uses: actions/checkout@v4413 - run: docker build -t app:${{ github.sha }} .414 - uses: aquasecurity/trivy-action@master415 with:416 image-ref: app:${{ github.sha }}417 severity: CRITICAL,HIGH418 exit-code: '1'419~420 sbom:421 name: SBOM Generation422 runs-on: ubuntu-latest423 needs: [container-scan]424 steps:425 - uses: actions/checkout@v4426 - uses: anchore/sbom-action@v0427 with:428 format: spdx-json429 output-file: sbom.spdx.json430```431~432```mermaid433graph TD434 PR[Pull Request] --> S1[Secret Detection]435 PR --> S2[SAST - Semgrep]436 PR --> S3[SCA - Snyk + npm audit]437 S2 --> S4[Container Scan - Trivy]438 S3 --> S4439 S4 --> S5[SBOM Generation]440 S5 --> Deploy[Deploy]441~442 S1 -.- F1[Block if secrets found]443 S2 -.- F2[Block on critical vulns]444 S3 -.- F3[Block on high severity]445 S4 -.- F4[Block on critical CVEs]446```447~448## Metrik untuk Dijejaki449~450Bagaimana anda tahu program DevSecOps anda berjaya? Jejaki metrik-metrik ini:451~452- **Mean time to remediate (MTTR)**: seberapa cepat anda membaiki kerentanan selepas pengesanan453- **Vulnerability escape rate**: peratusan kerentanan yang sampai ke production454- **False positive rate**: terlalu banyak positif palsu menyebabkan keletihan amaran dan amaran yang diabaikan455- **Dependency freshness**: purata umur dependency anda (lebih lama = lebih berkemungkinan mempunyai CVE yang diketahui)456- **SBOM coverage**: peratusan projek dengan SBOM yang terkini457~458## Bermula: Peta Jalan Praktikal459~460Jangan cuba melaksanakan semuanya sekaligus. Pendekatan berfasa berfungsi dengan lebih baik:461~462```mermaid463flowchart TD464 A[Week 1-2: Foundations] --> B[Week 3-4: CI/CD Integration]465 B --> C[Month 2: Container Security]466 C --> D[Month 3+: Advanced]467~468 A --> A1[Add Gitleaks pre-commit hooks]469 A --> A2[Enable npm audit in CI]470 A --> A3[Add .gitignore for .env files]471~472 B --> B1[Add Semgrep to GitHub Actions]473 B --> B2[Add Snyk dependency scanning]474 B --> B3[Set up SARIF upload to GitHub]475~476 C --> C1[Add Trivy container scanning]477 C --> C2[Harden Dockerfiles]478 C --> C3[Generate SBOMs]479~480 D --> D1[Secret manager integration]481 D --> D2[Runtime protection - DAST]482 D --> D3[Policy as code - OPA]483```484~485## Kesimpulan486~487DevSecOps bukan tentang menambah lebih banyak alat ke pipeline anda - ia tentang menjadikan keselamatan sebahagian semula jadi daripada cara anda membina perisian. Matlamatnya bukan menyekat setiap PR dengan amaran keselamatan tetapi memberi maklum balas pantas kepada pembangun supaya mereka boleh membaiki isu semasa kod masih segar dalam ingatan mereka.488~489Mulakan dengan asas: pre-commit hooks untuk secrets, dependency scanning dalam CI, dan container scanning untuk Docker images. Kemudian buat iterasi berdasarkan apa yang diperlukan pasukan anda.490~491Keselamatan bukan ciri yang anda hantar sekali. Ia adalah amalan yang anda bina ke dalam setiap commit.492~493> **DevSecOps Starter Checklist:**494>495> - [x] Gitleaks pre-commit hooks dipasang496> - [x] Fail .env dan secret dalam .gitignore497> - [x] Semgrep SAST dalam CI pipeline498> - [x] Snyk atau npm audit untuk imbasan dependency499> - [x] Trivy untuk imbasan container image500> - [x] Pengguna bukan root dalam Dockerfiles501> - [x] Secrets dalam environment variables atau secret manager502> - [x] Penjanaan SBOM pada setiap keluaran503> - [x] Kesedaran OWASP Top 10 di seluruh pasukan504~
NORMAL · devsecops-shift-left-security-guide.md [readonly]504 lines · :q to close