Zranitelnost 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.
DevSecOps 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.
Cena pozdni bezpecnosti
Zprava IBM Cost of a Data Breach soustavne ukazuje, ze naklady na opravu bezpecnostnich problemu rostou exponencialne, cim pozdeji jsou zachyceny:
| Faze | Naklady na opravu | Cas na opravu |
|---|---|---|
| IDE / Lokalni vyvoj | Minuty | Sekundy az minuty |
| Code Review / PR | Hodiny | Minuty az hodiny |
| Pipeline CI/CD | Dny | Hodiny az dny |
| Staging / QA | Tydny | Dny |
| Produkce | Mesice | Tydny az mesice |
| Po naruseni | Miliony ($) | Mesice az roky |
Zaver je jasny: kazda faze, o kterou posunete bezpecnost drive, usetri rad velikosti v nakladech a case.
Pipeline DevSecOps
Vyspelay pipeline DevSecOps integruje bezpecnostni kontroly v kazde fazi:
Pojdme si rozebrat kazdou fazi s konretnimi nastroji a konfiguraci.
Faze 1: Bezpecnost v IDE
Nejrychlejsi zpetna vazba. Zachytte zranitelnosti drive, nez vubec ulozite soubor.
Doporucene nastroje
- Semgrep: lehka staticka analyza s komunitnimi pravidly pro zranitelnosti OWASP
- Snyk IDE Extension: skenovani zranitelnosti zavislosti v realnem case
- GitLens + GitLeaks: detekce tajnych klicu ve vasem editoru
- ESLint Security Plugins:
eslint-plugin-securitypro Node.js,eslint-plugin-no-unsanitizedpro DOM XSS
Priklad: Konfigurace ESLint Security
{ "extends": ["eslint:recommended"], "plugins": ["security", "no-unsanitized"], "rules": { "security/detect-object-injection": "warn", "security/detect-non-literal-regexp": "warn", "security/detect-unsafe-regex": "error", "security/detect-buffer-noassert": "error", "security/detect-eval-with-expression": "error", "security/detect-no-csrf-before-method-override": "error", "security/detect-possible-timing-attacks": "warn", "no-unsanitized/method": "error", "no-unsanitized/property": "error" } }
Faze 2: Pre-commit Hooks
Druha linie obrany. Spousti se automaticky pred kazdym commitem a blokuje nebezpecny kod pred vstupem do repozitare.
Gitleaks: Zachytte tajne klice drive, nez se dostanou do Git
Nejcastejsi 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).
# .pre-commit-config.yaml repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.21.0 hooks: - id: gitleaks - repo: https://github.com/semgrep/semgrep rev: v1.90.0 hooks: - id: semgrep args: ['--config', 'auto']
Instalace a aktivace:
pip install pre-commit pre-commit install
Nyni kazdy git commit automaticky skenuje uniklye tajne klice a bezne zranitelnosti. Pokud je neco nalezeno, commit je zablokovany.
Vlastni pravidla Gitleaks
Muzete pridat vlastni vzory pro tajne klice vasi organizace:
# .gitleaks.toml title = "Custom Gitleaks Config" [[rules]] id = "internal-api-key" description = "Internal API key detected" regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}''' tags = ["key", "internal"]
Faze 3: Bezpecnost pipeline CI/CD
Zde se odehrava ta hlavni prace. Vas CI pipeline by mel spoustet vice bezpecnostnich skenu pri kazdem pull requestu.
SAST (Static Application Security Testing)
Nastroje SAST analyzuji zdrojovy kod bez jeho spousteni a hledaji vzory naznacujici zranitelnosti.
# .github/workflows/security.yml name: Security Scan on: pull_request: branches: [main] jobs: sast: name: Static Analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Semgrep uses: semgrep/semgrep-action@v1 with: config: >- p/owasp-top-ten p/typescript p/nodejs p/react generateSarif: true - name: Upload SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif
Sada pravidel p/owasp-top-ten od Semgrep zachytava nejcastejsi zranitelnosti: SQL injection, XSS, SSRF, path traversal, insecure deserialization a dalsi.
SCA (Software Composition Analysis)
SCA skenuje vase zavislosti na zname zranitelnosti. To je kriticke - pres 80 % kodu modernich aplikaci pochazi ze zavislosti open-source.
dependency-scan: name: Dependency Audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Snyk uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high - name: npm audit run: npm audit --audit-level=high
Bezpecnost kontejneru s Trivy
Pokud sestavujete obrazy Docker, jejich skenovani na zranitelnosti je nezbytne. Trivy je nejpopularnejsi open-source skener kontejneru.
container-scan: name: Container Security runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build image run: docker build -t my-app:${{ github.sha }} . - name: Run Trivy uses: aquasecurity/trivy-action@master with: image-ref: my-app:${{ github.sha }} format: 'sarif' output: 'trivy-results.sarif' severity: 'CRITICAL,HIGH' exit-code: '1' - name: Upload Trivy SARIF uses: github/codeql-action/upload-sarif@v3 with: sarif_file: trivy-results.sarif
Generovani SBOM
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).
sbom: name: Generate SBOM runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Generate SBOM with Syft uses: anchore/sbom-action@v0 with: format: spdx-json output-file: sbom.spdx.json - name: Upload SBOM uses: actions/upload-artifact@v4 with: name: sbom path: sbom.spdx.json
Faze 4: Bezpecne obrazy Docker
Produkcni obraz Docker by mel dodrzovat zasadu nejmensich opravneni. Takto vypada zpevneny Dockerfile:
# Build stage FROM node:22-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Production stage FROM node:22-alpine AS runner WORKDIR /app # Install dumb-init before dropping root RUN apk add --no-cache dumb-init # Don't run as root RUN addgroup -S app && adduser -S app -G app # Copy only what's needed COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ # Drop to non-root user USER app ENTRYPOINT ["dumb-init", "--"] # Health check HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1 EXPOSE 3000 CMD ["node", "dist/server.js"]
Klicove postupy:
- Pouzivejte multi-stage builds: faze builder ma vyvojove zavislosti; faze runner ma pouze produkcni kod
- Nespoustejte jako root: vytvorte uzivatele bez root opravneni a prepnete na nej
- Pouzivejte obrazy Alpine: mensi plocha pro utok (mene balicku nainstalovanych ve vychozim stavu)
- Pripnete verze obrazu:
node:22-alpinenamistonode:latestpro predchazeni utokum na dodavatelsky retezec - Pouzivejte
npm ci: deterministicke instalace z lock souboru, nenpm install
Faze 5: Sprava tajnych klicu
Napevno zakodovane tajne klice jsou pricionu cislo jedna naruseni u incidentu zpusobenych vyvojari.
Co NEDELAT
// NEVER do this const API_KEY = "sk-1234567890abcdef"; const DB_PASSWORD = "supersecret123"; const client = new Client({ connectionString: `postgres://admin:${DB_PASSWORD}@db.example.com/prod` });
Co delat misto toho
// Use environment variables const client = new Client({ connectionString: process.env.DATABASE_URL }); // Or use a secret manager import { SecretManagerServiceClient } from '@google-cloud/secret-manager'; const client = new SecretManagerServiceClient(); const [version] = await client.accessSecretVersion({ name: 'projects/my-project/secrets/db-password/versions/latest', }); const dbPassword = version.payload?.data?.toString();
Hierarchie spravy tajnych klicu
OWASP Top 10: Strucny prehled
Kazdy vyvojar by mel znat OWASP Top 10. Zkracena verze:
| # | Zranitelnost | Co to je | Prevence |
|---|---|---|---|
| 1 | Broken Access Control | Uzivatele pristupuji k prostredkum, ke kterym by nemeli mit pristup | Ve vychozim stavu odmitnout, validovat na strane serveru |
| 2 | Cryptographic Failures | Slabe sifrovani, data v cistem textu | Silne algoritmy (AES-256, bcrypt), TLS vsude |
| 3 | Injection | SQL, NoSQL, OS command injection | Parametrizovane dotazy, validace vstupu |
| 4 | Insecure Design | Chybna architektura | Modelovani hrozeb, bezpecne navrhove vzory |
| 5 | Security Misconfiguration | Vychozi prihlasovaci udaje, otevrene cloud buckety | Zpevnene vychozi nastaveni, automatizovane audity konfigurace |
| 6 | Vulnerable Components | Zname CVE v zavislostech | Skenovani SCA, pravidelne aktualizace |
| 7 | Auth Failures | Slaba hesla, narusene relace | MFA, rate limiting, bezpecna sprava relaci |
| 8 | Data Integrity Failures | Nepodepsane aktualizace, neduveryhodne CI/CD | Podepisovani kodu, SBOM, integrita pipeline |
| 9 | Logging Failures | Zadna auditni stopa | Strukturovane logovani, alertovani na anomalie |
| 10 | SSRF | Server-side request forgery | Allowlist odchozich URL, validace vstupu |
Kompletni bezpecnostni workflow v GitHub Actions
Kompletni workflow pripraveny pro produkci, ktery kombinuje vse vyse uvedene:
# .github/workflows/security.yml name: Security Pipeline on: pull_request: branches: [main] push: branches: [main] permissions: contents: read security-events: write jobs: secrets-scan: name: Secret Detection runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: gitleaks/gitleaks-action@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} sast: name: Static Analysis (SAST) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: semgrep/semgrep-action@v1 with: config: p/owasp-top-ten p/typescript p/nodejs dependency-audit: name: Dependency Scan (SCA) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - run: npm ci - run: npm audit --audit-level=high - uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high continue-on-error: true container-scan: name: Container Scan runs-on: ubuntu-latest needs: [sast, dependency-audit] steps: - uses: actions/checkout@v4 - run: docker build -t app:${{ github.sha }} . - uses: aquasecurity/trivy-action@master with: image-ref: app:${{ github.sha }} severity: CRITICAL,HIGH exit-code: '1' sbom: name: SBOM Generation runs-on: ubuntu-latest needs: [container-scan] steps: - uses: actions/checkout@v4 - uses: anchore/sbom-action@v0 with: format: spdx-json output-file: sbom.spdx.json
Metriky ke sledovani
Jak poznate, ze vas program DevSecOps funguje? Sledujte tyto metriky:
- Mean time to remediate (MTTR): jak rychle opravujete zranitelnosti po jejich detekci
- Vulnerability escape rate: procento zranitelnosti, ktere se dostanou do produkce
- False positive rate: prilis mnoho falesnych pozitivnich hlaseni vede k unave z alertu a ignorovani varovani
- Dependency freshness: prumerny vek vasich zavislosti (starsi = vetsi pravdepodobnost znamych CVE)
- SBOM coverage: procento projektu s aktualizovanymi SBOM
Jak zacit: Prakticky plan
Nesnazete se implementovat vse najednou. Fazovy pristup funguje lepe:
Zaver
DevSecOps 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.
Zacnete 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.
Bezpecnost neni funkce, kterou dodavate jednou. Je to praxe, kterou zabudovavate do kazdeho commitu.
Kontrolni seznam DevSecOps pro zacatek:
- Nainstalovane pre-commit hooks Gitleaks
- Soubory .env a soubory s tajnymi klici v .gitignore
- Semgrep SAST v CI pipeline
- Snyk nebo npm audit pro skenovani zavislosti
- Trivy pro skenovani obrazu kontejneru
- Uzivatel bez root opravneni v Dockerfile
- Tajne klice v promennych prostredi nebo secret manager
- Generovani SBOM pri kazdem vydani
- Povedomi o OWASP Top 10 v celem tymu