spinny:~/writing $ vim devsecops-shift-left-security-guide.md
1~2Zranitelnost nalezena behem psani kodu stoji vyvojare minuty na opravu. Stejna zranitelnost zachycena v produkci stoji cely sprint. A pokud ji najde utocnik jako prvni, stoji miliony. To je hlavni argument pro **shift-left security** - presouvani bezpecnostnich kontrol co nejdrive v zivotnim cyklu vyvoje.3~4DevSecOps bere tuto myslenku a premeni ji v praxi: bezpecnost neni oddelena faze na konci, ale nepretrzity proces vpleteny do kazde faze vyvoje - od prvniho radku kodu az po nasazeni do produkce.5~6## Cena pozdni bezpecnosti7~8Zprava IBM Cost of a Data Breach soustavne ukazuje, ze naklady na opravu bezpecnostnich problemu rostou exponencialne, cim pozdeji jsou zachyceny:9~10| Faze | Naklady na opravu | Cas na opravu |11|------|-------------------|---------------|12| **IDE / Lokalni vyvoj** | Minuty | Sekundy az minuty |13| **Code Review / PR** | Hodiny | Minuty az hodiny |14| **Pipeline CI/CD** | Dny | Hodiny az dny |15| **Staging / QA** | Tydny | Dny |16| **Produkce** | Mesice | Tydny az mesice |17| **Po naruseni** | Miliony ($) | Mesice az roky |18~19Zaver je jasny: kazda faze, o kterou posunete bezpecnost drive, usetri rad velikosti v nakladech a case.20~21## Pipeline DevSecOps22~23Vyspelay pipeline DevSecOps integruje bezpecnostni kontroly v kazde fazi: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~43Pojdme si rozebrat kazdou fazi s konretnimi nastroji a konfiguraci.44~45## Faze 1: Bezpecnost v IDE46~47Nejrychlejsi zpetna vazba. Zachytte zranitelnosti drive, nez vubec ulozite soubor.48~49### Doporucene nastroje50~51- **Semgrep**: lehka staticka analyza s komunitnimi pravidly pro zranitelnosti OWASP52- **Snyk IDE Extension**: skenovani zranitelnosti zavislosti v realnem case53- **GitLens + GitLeaks**: detekce tajnych klicu ve vasem editoru54- **ESLint Security Plugins**: `eslint-plugin-security` pro Node.js, `eslint-plugin-no-unsanitized` pro DOM XSS55~56### Priklad: Konfigurace 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## Faze 2: Pre-commit Hooks77~78Druha linie obrany. Spousti se automaticky pred kazdym commitem a blokuje nebezpecny kod pred vstupem do repozitare.79~80### Gitleaks: Zachytte tajne klice drive, nez se dostanou do Git81~82Nejcastejsi bezpecnostni chybou v kodovych bazich je commitovani tajnych klicu - API klicu, hesel k databazim, tokenu. Jakmile se tajny klic dostane do historie git, je extremne tezke jej uplne odstranit (i pri force push mohou forky a cache uchovat kopii).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~99Instalace a aktivace:100~101```bash102pip install pre-commit103pre-commit install104```105~106Nyni kazdy `git commit` automaticky skenuje uniklye tajne klice a bezne zranitelnosti. Pokud je neco nalezeno, commit je zablokovany.107~108### Vlastni pravidla Gitleaks109~110Muzete pridat vlastni vzory pro tajne klice vasi organizace: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## Faze 3: Bezpecnost pipeline CI/CD124~125Zde se odehrava ta hlavni prace. Vas CI pipeline by mel spoustet vice bezpecnostnich skenu pri kazdem pull requestu.126~127### SAST (Static Application Security Testing)128~129Nastroje SAST analyzuji zdrojovy kod bez jeho spousteni a hledaji vzory naznacujici zranitelnosti.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~161Sada pravidel `p/owasp-top-ten` od Semgrep zachytava nejcastejsi zranitelnosti: SQL injection, XSS, SSRF, path traversal, insecure deserialization a dalsi.162~163### SCA (Software Composition Analysis)164~165SCA skenuje vase zavislosti na zname zranitelnosti. To je kriticke - pres 80 % kodu modernich aplikaci pochazi ze zavislosti 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### Bezpecnost kontejneru s Trivy186~187Pokud sestavujete obrazy Docker, jejich skenovani na zranitelnosti je nezbytne. **Trivy** je nejpopularnejsi open-source skener kontejneru.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### Generovani SBOM215~216**Software Bill of Materials (SBOM)** je uplny inventar kazde komponenty ve vasi aplikaci. Stale casteji je vyzadovany frameworky pro shodu a vladnimi predpisy (exekutivni prikaz prezidenta USA o kyberneticke bezpecnosti narizuje SBOM pro federalni software).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## Faze 4: Bezpecne obrazy Docker239~240Produkcni obraz Docker by mel dodrzovat zasadu nejmensich opravneni. Takto vypada zpevneny Dockerfile: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~278Klicove postupy:279~2801. **Pouzivejte multi-stage builds**: faze builder ma vyvojove zavislosti; faze runner ma pouze produkcni kod2812. **Nespoustejte jako root**: vytvorte uzivatele bez root opravneni a prepnete na nej2823. **Pouzivejte obrazy Alpine**: mensi plocha pro utok (mene balicku nainstalovanych ve vychozim stavu)2834. **Pripnete verze obrazu**: `node:22-alpine` namisto `node:latest` pro predchazeni utokum na dodavatelsky retezec2845. **Pouzivejte `npm ci`**: deterministicke instalace z lock souboru, ne `npm install`285~286## Faze 5: Sprava tajnych klicu287~288Napevno zakodovane tajne klice jsou pricionu cislo jedna naruseni u incidentu zpusobenych vyvojari.289~290### Co NEDELAT291~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### Co delat misto toho303~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### Hierarchie spravy tajnych klicu321~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: Strucny prehled336~337Kazdy vyvojar by mel znat OWASP Top 10. Zkracena verze:338~339| # | Zranitelnost | Co to je | Prevence |340|---|-------------|---------|----------|341| 1 | **Broken Access Control** | Uzivatele pristupuji k prostredkum, ke kterym by nemeli mit pristup | Ve vychozim stavu odmitnout, validovat na strane serveru |342| 2 | **Cryptographic Failures** | Slabe sifrovani, data v cistem textu | Silne algoritmy (AES-256, bcrypt), TLS vsude |343| 3 | **Injection** | SQL, NoSQL, OS command injection | Parametrizovane dotazy, validace vstupu |344| 4 | **Insecure Design** | Chybna architektura | Modelovani hrozeb, bezpecne navrhove vzory |345| 5 | **Security Misconfiguration** | Vychozi prihlasovaci udaje, otevrene cloud buckety | Zpevnene vychozi nastaveni, automatizovane audity konfigurace |346| 6 | **Vulnerable Components** | Zname CVE v zavislostech | Skenovani SCA, pravidelne aktualizace |347| 7 | **Auth Failures** | Slaba hesla, narusene relace | MFA, rate limiting, bezpecna sprava relaci |348| 8 | **Data Integrity Failures** | Nepodepsane aktualizace, neduveryhodne CI/CD | Podepisovani kodu, SBOM, integrita pipeline |349| 9 | **Logging Failures** | Zadna auditni stopa | Strukturovane logovani, alertovani na anomalie |350| 10 | **SSRF** | Server-side request forgery | Allowlist odchozich URL, validace vstupu |351~352## Kompletni bezpecnostni workflow v GitHub Actions353~354Kompletni workflow pripraveny pro produkci, ktery kombinuje vse vyse uvedene: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## Metriky ke sledovani449~450Jak poznate, ze vas program DevSecOps funguje? Sledujte tyto metriky:451~452- **Mean time to remediate (MTTR)**: jak rychle opravujete zranitelnosti po jejich detekci453- **Vulnerability escape rate**: procento zranitelnosti, ktere se dostanou do produkce454- **False positive rate**: prilis mnoho falesnych pozitivnich hlaseni vede k unave z alertu a ignorovani varovani455- **Dependency freshness**: prumerny vek vasich zavislosti (starsi = vetsi pravdepodobnost znamych CVE)456- **SBOM coverage**: procento projektu s aktualizovanymi SBOM457~458## Jak zacit: Prakticky plan459~460Nesnazete se implementovat vse najednou. Fazovy pristup funguje lepe: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## Zaver486~487DevSecOps neni o pridavani dalsich nastroju do vaseho pipeline - je to o tom, aby se bezpecnost stala prirozeno soucastu zpusobu, jakym stavite software. Cilem neni blokovat kazdy PR bezpecnostnimi varovanimi, ale poskytnout vyvojarum rychlou zpetnou vazbu, aby mohli opravovat problemy, dokud maji kod jeste cerstvo v pameti.488~489Zacnete se zaklady: pre-commit hooks pro tajne klice, skenovani zavislosti v CI a skenovani kontejneru pro obrazy Docker. Pak iterujte na zaklade toho, co vas tym potrebuje.490~491Bezpecnost neni funkce, kterou dodavate jednou. Je to praxe, kterou zabudovavate do kazdeho commitu.492~493> **Kontrolni seznam DevSecOps pro zacatek:**494>495> - [x] Nainstalovane pre-commit hooks Gitleaks496> - [x] Soubory .env a soubory s tajnymi klici v .gitignore497> - [x] Semgrep SAST v CI pipeline498> - [x] Snyk nebo npm audit pro skenovani zavislosti499> - [x] Trivy pro skenovani obrazu kontejneru500> - [x] Uzivatel bez root opravneni v Dockerfile501> - [x] Tajne klice v promennych prostredi nebo secret manager502> - [x] Generovani SBOM pri kazdem vydani503> - [x] Povedomi o OWASP Top 10 v celem tymu504~
NORMAL · devsecops-shift-left-security-guide.md [readonly]504 lines · :q to close