spinny:~/writing $ less devsecops-shift-left-security-guide.md
12En sarbarhet som upptaecks medan du skriver kod kostar en utvecklare minuter att atgaerda. Samma sarbarhet som foangas i produktion kostar en sprint. Och om en angripare hittar den foerst kostar det miljoner. Detta aer karnargumentet bakom **shift-left security** - att flytta saekerhetskontroller sa tidigt som moejligt i utvecklingscykeln.34DevSecOps tar denna ide och goer den till praktik: saekerhet aer inte en separat fas i slutet utan en kontinuerlig process som aer invaevd i varje steg av utvecklingen - fran den foersta kodraden till produktionsdistributionen.56## Kostnaden foer Sen Saekerhet78IBM:s Cost of a Data Breach Report har konsekvent visat att kostnaden foer att atgaerda saekerhetsbrister vaexer exponentiellt ju senare de upptaecks:910| Fas | Kostnad att atgaerda | Tid att atgaerda |11|-----|----------------------|------------------|12| **IDE / Lokal utveckling** | Minuter | Sekunder till minuter |13| **Code Review / PR** | Timmar | Minuter till timmar |14| **CI/CD Pipeline** | Dagar | Timmar till dagar |15| **Staging / QA** | Veckor | Dagar |16| **Produktion** | Manader | Veckor till manader |17| **Efter introng** | Miljoner ($) | Manader till ar |1819Slutsatsen aer tydlig: varje steg du flyttar saekerheten tidigare sparar en storleksordning i kostnad och tid.2021## DevSecOps Pipeline2223En mogen DevSecOps pipeline integrerar saekerhetskontroller i varje steg:2425```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]3334 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```4243Lat oss ga igenom varje steg med konkreta verktyg och konfiguration.4445## Steg 1: Saekerhet i IDE:n4647Den snabbaste feedback-loopen. Fanga sarbarheter innan du ens sparar filen.4849### Rekommenderade Verktyg5051- **Semgrep**: laettviktig statisk analys med community-regler foer OWASP-sarbarheter52- **Snyk IDE Extension**: realtidsskanning av sarbarheter i dependencies53- **GitLens + GitLeaks**: upptaeck secrets i din editor54- **ESLint Security Plugins**: `eslint-plugin-security` foer Node.js, `eslint-plugin-no-unsanitized` foer DOM XSS5556### Exempel: ESLint Security-konfiguration5758```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```7576## Steg 2: Pre-commit Hooks7778Den andra foersvarslinjen. Koers automatiskt foere varje commit och blockerar farlig kod fran att na repositoryt.7980### Gitleaks: Fanga Secrets innan de nar Git8182Det vanligaste saekerhetsmisstaget i kodbaser aer att committa secrets - API keys, databasloesen, tokens. Nar en secret vaeal hamnar i git-historiken aer det extremt svart att ta bort den helt (aeven med force pushes kan forks och cachar behalla den).8384```yaml85# .pre-commit-config.yaml86repos:87 - repo: https://github.com/gitleaks/gitleaks88 rev: v8.21.089 hooks:90 - id: gitleaks9192 - repo: https://github.com/semgrep/semgrep93 rev: v1.90.094 hooks:95 - id: semgrep96 args: ['--config', 'auto']97```9899Installera och aktivera:100101```bash102pip install pre-commit103pre-commit install104```105106Nu skannar varje `git commit` automatiskt efter laeckta secrets och vanliga sarbarheter. Om nagot hittas blockeras committen.107108### Anpassade Gitleaks-regler109110Du kan laegga till anpassade moenster foer din organisations secrets:111112```toml113# .gitleaks.toml114title = "Custom Gitleaks Config"115116[[rules]]117id = "internal-api-key"118description = "Internal API key detected"119regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}'''120tags = ["key", "internal"]121```122123## Steg 3: CI/CD Pipeline Security124125Haer goers det tunga arbetet. Din CI pipeline boer koera flera saekerhetskanningar vid varje pull request.126127### SAST (Static Application Security Testing)128129SAST-verktyg analyserar kaellkod utan att koera den och letar efter moenster som indikerar sarbarheter.130131```yaml132# .github/workflows/security.yml133name: Security Scan134on:135 pull_request:136 branches: [main]137138jobs:139 sast:140 name: Static Analysis141 runs-on: ubuntu-latest142 steps:143 - uses: actions/checkout@v4144145 - name: Run Semgrep146 uses: semgrep/semgrep-action@v1147 with:148 config: >-149 p/owasp-top-ten150 p/typescript151 p/nodejs152 p/react153 generateSarif: true154155 - name: Upload SARIF156 uses: github/codeql-action/upload-sarif@v3157 with:158 sarif_file: semgrep.sarif159```160161Semgreps ruleset `p/owasp-top-ten` fangar de vanligaste sarbarheterna: SQL injection, XSS, SSRF, path traversal, insecure deserialization och mer.162163### SCA (Software Composition Analysis)164165SCA skannar dina dependencies efter kaenda sarbarheter. Detta aer kritiskt - oever 80% av koden i moderna applikationer kommer fran open-source dependencies.166167```yaml168 dependency-scan:169 name: Dependency Audit170 runs-on: ubuntu-latest171 steps:172 - uses: actions/checkout@v4173174 - name: Run Snyk175 uses: snyk/actions/node@master176 env:177 SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}178 with:179 args: --severity-threshold=high180181 - name: npm audit182 run: npm audit --audit-level=high183```184185### Container Security med Trivy186187Om du bygger Docker images aer det vasentligt att skanna dem efter sarbarheter. **Trivy** aer den mest populaera open-source container-skannern.188189```yaml190 container-scan:191 name: Container Security192 runs-on: ubuntu-latest193 steps:194 - uses: actions/checkout@v4195196 - name: Build image197 run: docker build -t my-app:${{ github.sha }} .198199 - 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'207208 - name: Upload Trivy SARIF209 uses: github/codeql-action/upload-sarif@v3210 with:211 sarif_file: trivy-results.sarif212```213214### SBOM-generering215216En **Software Bill of Materials (SBOM)** aer en komplett inventering av varje komponent i din applikation. Den kraevs alltmer av compliance-ramverk och statliga regleringar (den amerikanska Executive Order on Cybersecurity kraever SBOM foer federal programvara).217218```yaml219 sbom:220 name: Generate SBOM221 runs-on: ubuntu-latest222 steps:223 - uses: actions/checkout@v4224225 - name: Generate SBOM with Syft226 uses: anchore/sbom-action@v0227 with:228 format: spdx-json229 output-file: sbom.spdx.json230231 - name: Upload SBOM232 uses: actions/upload-artifact@v4233 with:234 name: sbom235 path: sbom.spdx.json236```237238## Steg 4: Saekra Docker Images239240En produktions-Docker-image boer foelja principen om laegsta behoerigheter. Sa haer ser en haerdad Dockerfile ut:241242```dockerfile243# Build stage244FROM node:22-alpine AS builder245WORKDIR /app246COPY package.json package-lock.json ./247RUN npm ci248COPY . .249RUN npm run build250251# Production stage252FROM node:22-alpine AS runner253WORKDIR /app254255# Install dumb-init before dropping root256RUN apk add --no-cache dumb-init257258# Don't run as root259RUN addgroup -S app && adduser -S app -G app260261# 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 ./265266# Drop to non-root user267USER app268ENTRYPOINT ["dumb-init", "--"]269270# Health check271HEALTHCHECK --interval=30s --timeout=3s --retries=3 \272 CMD wget -qO- http://localhost:3000/health || exit 1273274EXPOSE 3000275CMD ["node", "dist/server.js"]276```277278Viktiga principer:2792801. **Anvaend multi-stage builds**: builder-steget har dev-dependencies; runner-steget har bara produktionskod2812. **Koer inte som root**: skapa en icke-root-anvaendare och byt till den2823. **Anvaend Alpine images**: mindre attackyta (faerre paket installerade som standard)2834. **Fixera image-versioner**: `node:22-alpine` istaellet foer `node:latest` foer att undvika supply chain-attacker2845. **Anvaend `npm ci`**: deterministiska installationer fran lock-filen, inte `npm install`285286## Steg 5: Secret Management287288Haerdkodade secrets aer den vanligaste orsaken till introng vid utvecklarorsaktade incidenter.289290### Vad du INTE ska goera291292```typescript293// NEVER do this294const API_KEY = "sk-1234567890abcdef";295const DB_PASSWORD = "supersecret123";296297const client = new Client({298 connectionString: `postgres://admin:${DB_PASSWORD}@db.example.com/prod`299});300```301302### Vad du ska goera istaellet303304```typescript305// Use environment variables306const client = new Client({307 connectionString: process.env.DATABASE_URL308});309310// Or use a secret manager311import { SecretManagerServiceClient } from '@google-cloud/secret-manager';312313const 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```319320### Secret Management-hierarki321322```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]328329 style A fill:#d4edda330 style C fill:#fff3cd331 style E fill:#ffeeba332 style G fill:#f8d7da333```334335## OWASP Top 10: En Snabbreferens336337Varje utvecklare boer kaenna till OWASP Top 10. Sammanfattad version:338339| # | Sarbarhet | Vad det aer | Foerebyggande |340|---|-----------|-------------|---------------|341| 1 | **Broken Access Control** | Anvaendare som far atkomst till resurser de inte boer ha | Neka som standard, validera pa serversidan |342| 2 | **Cryptographic Failures** | Svag kryptering, data i klartext | Anvaend starka algoritmer (AES-256, bcrypt), TLS oeverallt |343| 3 | **Injection** | SQL, NoSQL, OS command injection | Parametriserade fragor, inmatningsvalidering |344| 4 | **Insecure Design** | Bristfaellig arkitektur | Threat modeling, saekra designmoenster |345| 5 | **Security Misconfiguration** | Standardinloggningar, oeppna cloud buckets | Haerdade standardvaerden, automatiserade konfigurationsgranskningar |346| 6 | **Vulnerable Components** | Kaenda CVEs i dependencies | SCA scanning, regelmaessiga uppdateringar |347| 7 | **Auth Failures** | Svaga loesenord, trasiga sessioner | MFA, rate limiting, saeker session management |348| 8 | **Data Integrity Failures** | Osignerade uppdateringar, opaalitlig CI/CD | Code signing, SBOM, pipeline-integritet |349| 9 | **Logging Failures** | Ingen revisionslogg | Strukturerad logging, larm vid avvikelser |350| 10 | **SSRF** | Server-side request forgery | Allowlist foer utgaende URLs, validera inmatningar |351352## Komplett GitHub Actions Security Workflow353354Ett komplett, produktionsredo arbetsfoede som kombinerar allt ovan:355356```yaml357# .github/workflows/security.yml358name: Security Pipeline359on:360 pull_request:361 branches: [main]362 push:363 branches: [main]364365permissions:366 contents: read367 security-events: write368369jobs: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 }}380381 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/nodejs389390 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: true406407 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'419420 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```431432```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]441442 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```447448## Maetetal att Foelja449450Hur vet du att ditt DevSecOps-program fungerar? Foelja dessa maetetal:451452- **Mean Time to Remediate (MTTR)**: hur snabbt du atgaerdar sarbarheter efter upptaeckt453- **Vulnerability Escape Rate**: andelen sarbarheter som nar produktion454- **False Positive Rate**: foer manga false positives leder till larmtroetthet och ignorerade varningar455- **Dependency Freshness**: genomsnittsalder pa dina dependencies (aeldre = stoerre sannolikhet foer kaenda CVEs)456- **SBOM Coverage**: andelen projekt med uppdaterade SBOMs457458## Komma Igang: En Praktisk Faerdplan459460Foersoek inte implementera allt pa en gang. En stegvis ansats fungerar baettre:461462```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]467468 A --> A1[Add Gitleaks pre-commit hooks]469 A --> A2[Enable npm audit in CI]470 A --> A3[Add .gitignore for .env files]471472 B --> B1[Add Semgrep to GitHub Actions]473 B --> B2[Add Snyk dependency scanning]474 B --> B3[Set up SARIF upload to GitHub]475476 C --> C1[Add Trivy container scanning]477 C --> C2[Harden Dockerfiles]478 C --> C3[Generate SBOMs]479480 D --> D1[Secret manager integration]481 D --> D2[Runtime protection - DAST]482 D --> D3[Policy as code - OPA]483```484485## Slutsats486487DevSecOps handlar inte om att laegga till fler verktyg i din pipeline - det handlar om att goera saekerhet till en naturlig del av hur du bygger programvara. Malet aer inte att blockera varje PR med saekerhetsvarningar utan att ge utvecklare snabb feedback sa att de kan atgaerda problem medan koden fortfarande aer faersk i minnet.488489Boerja med grunderna: pre-commit hooks foer secrets, dependency scanning i CI och container scanning foer Docker images. Iterera sedan baserat pa vad ditt team behoever.490491Saekerhet aer inte en funktion du levererar en gang. Det aer en praxis du bygger in i varje commit.492493> **DevSecOps Starter Checklista:**494>495> - [x] Gitleaks pre-commit hooks installerade496> - [x] .env och secret-filer i .gitignore497> - [x] Semgrep SAST i CI pipeline498> - [x] Snyk eller npm audit foer dependency scanning499> - [x] Trivy foer container image scanning500> - [x] Icke-root-anvaendare i Dockerfiles501> - [x] Secrets i miljoevariablar eller secret manager502> - [x] SBOM-generering vid varje release503> - [x] OWASP Top 10-medvetenhet i hela teamet504
:DevSecOps foer Utvecklare: En Praktisk Guide till Shift-Left Securitylines 1-504 (END) — press q to close