spinny:~/writing $ less devsecops-shift-left-security-guide.md
12O vulnerabilitate gasita in timp ce scrii cod costa un dezvoltator cateva minute pentru a o repara. Aceeasi vulnerabilitate detectata in productie costa un sprint. Iar daca un atacator o gaseste primul, costa milioane. Acesta este argumentul central al **shift-left security** - mutarea controalelor de securitate cat mai devreme posibil in ciclul de viata al dezvoltarii.34DevSecOps preia aceasta idee si o transforma intr-o practica: securitatea nu este o faza separata la sfarsit, ci un proces continuu integrat in fiecare etapa a dezvoltarii, de la prima linie de cod pana la deploy-ul in productie.56## Costul securitatii tardive78Raportul Cost of a Data Breach de la IBM a demonstrat in mod constant ca costul remedierii problemelor de securitate creste exponential cu cat sunt detectate mai tarziu:910| Etapa | Cost de remediere | Timp de remediere |11|-------|-------------------|-------------------|12| **IDE / Dezvoltare locala** | Minute | Secunde pana la minute |13| **Code review / PR** | Ore | Minute pana la ore |14| **Pipeline CI/CD** | Zile | Ore pana la zile |15| **Staging / QA** | Saptamani | Zile |16| **Productie** | Luni | Saptamani pana la luni |17| **Post-breach** | Milioane ($) | Luni pana la ani |1819Concluzia este clara: fiecare etapa in care avansezi securitatea economiseste un ordin de marime in costuri si timp.2021## Pipeline-ul DevSecOps2223Un pipeline DevSecOps matur integreaza controale de securitate in fiecare etapa: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```4243Sa analizam fiecare etapa cu instrumente si configuratii concrete.4445## Etapa 1: securitate in IDE4647Cel mai rapid ciclu de feedback. Detecteaza vulnerabilitatile inainte sa salvezi fisierul.4849### Instrumente recomandate5051- **Semgrep**: analiza statica usoara cu reguli comunitare pentru vulnerabilitatile OWASP52- **Snyk IDE Extension**: scanare in timp real a vulnerabilitatilor din dependente53- **GitLens + GitLeaks**: detecteaza secrets in editorul tau54- **ESLint Security Plugins**: `eslint-plugin-security` pentru Node.js, `eslint-plugin-no-unsanitized` pentru DOM XSS5556### Exemplu: configurare ESLint pentru securitate5758```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## Etapa 2: Pre-commit Hooks7778A doua linie de aparare. Se executa automat inainte de fiecare commit, blocand codul periculos sa intre in repository.7980### Gitleaks: intercepteaza secrets inainte sa ajunga in Git8182Cea mai comuna greseala de securitate in codebases este sa faci commit la secrets - chei API, parole de baze de date, tokeni. Odata ce un secret ajunge in istoricul git, este extrem de dificil de eliminat complet (chiar si cu force pushes, fork-urile si cache-urile il pot retine).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```9899Instaleaza si activeaza:100101```bash102pip install pre-commit103pre-commit install104```105106Acum fiecare `git commit` scaneaza automat dupa secrets scapate si vulnerabilitati comune. Daca se gaseste ceva, commit-ul este blocat.107108### Reguli Gitleaks personalizate109110Poti adauga pattern-uri personalizate pentru secrets specifice organizatiei tale: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## Etapa 3: securitatea pipeline-ului CI/CD124125Aici se intampla munca grea. Pipeline-ul tau CI ar trebui sa ruleze mai multe scanari de securitate la fiecare pull request.126127### SAST (Static Application Security Testing)128129Instrumentele SAST analizeaza codul sursa fara a-l executa, cautand pattern-uri care indica vulnerabilitati.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```160161Ruleset-ul `p/owasp-top-ten` de la Semgrep detecteaza cele mai comune vulnerabilitati: SQL injection, XSS, SSRF, path traversal, deserializare nesigura si altele.162163### SCA (Software Composition Analysis)164165SCA scaneaza dependentele tale in cautarea vulnerabilitatilor cunoscute. Acest lucru este esential - peste 80% din codul aplicatiilor moderne provine din dependente open-source.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### Securitatea containerelor cu Trivy186187Daca construiesti imagini Docker, scanarea lor pentru vulnerabilitati este esentiala. **Trivy** este cel mai popular scanner de containere open-source.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### Generarea SBOM215216O **Software Bill of Materials (SBOM)** este un inventar complet al fiecarui component din aplicatia ta. Este din ce in ce mai ceruta de cadrele de conformitate si reglementarile guvernamentale (Ordinul Executiv al SUA privind Securitatea Cibernetica impune SBOM pentru software-ul federal).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## Etapa 4: imagini Docker securizate239240O imagine Docker de productie ar trebui sa urmeze principiul celui mai mic privilegiu. Iata cum arata un Dockerfile intarit: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```277278Practici cheie:2792801. **Foloseste build-uri multi-stage**: stage-ul builder are dependentele de dezvoltare; stage-ul runner are doar codul de productie2812. **Nu rula ca root**: creeaza un utilizator non-root si comuta la el2823. **Foloseste imagini Alpine**: suprafata de atac redusa (mai putine pachete instalate implicit)2834. **Fixeaza versiunile imaginilor**: `node:22-alpine` in loc de `node:latest` pentru a evita atacurile la supply chain2845. **Foloseste `npm ci`**: instalari deterministe din lock file, nu `npm install`285286## Etapa 5: gestionarea secrets287288Secrets hard-coded sunt cauza numarul unu a bresuilor in incidentele cauzate de dezvoltatori.289290### Ce sa NU faci291292```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### Ce sa faci in schimb303304```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### Ierarhia gestionarii secrets321322```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: referinta rapida336337Fiecare dezvoltator ar trebui sa cunoasca OWASP Top 10. Versiune condensata:338339| # | Vulnerabilitate | Ce este | Preventie |340|---|-----------------|---------|-----------|341| 1 | **Broken Access Control** | Utilizatori accesand resurse neautorizate | Refuza implicit, valideaza pe server |342| 2 | **Cryptographic Failures** | Criptare slaba, date in text clar | Foloseste algoritmi robusti (AES-256, bcrypt), TLS peste tot |343| 3 | **Injection** | SQL, NoSQL, OS command injection | Interogari parametrizate, validarea intrarilor |344| 4 | **Insecure Design** | Arhitectura cu defecte | Threat modeling, secure design patterns |345| 5 | **Security Misconfiguration** | Credentiale implicite, bucket-uri cloud deschise | Valori implicite intarite, audituri automate ale configuratiei |346| 6 | **Vulnerable Components** | CVE-uri cunoscute in dependente | Scanare SCA, actualizari regulate |347| 7 | **Auth Failures** | Parole slabe, sesiuni compromise | MFA, rate limiting, gestionare securizata a sesiunilor |348| 8 | **Data Integrity Failures** | Actualizari nesemnate, CI/CD neincrezator | Code signing, SBOM, integritatea pipeline-ului |349| 9 | **Logging Failures** | Fara pista de audit | Logging structurat, alerte la anomalii |350| 10 | **SSRF** | Server-side request forgery | Allowlist pentru URL-uri de iesire, validarea intrarilor |351352## Workflow complet de securitate cu GitHub Actions353354Un workflow complet si pregatit pentru productie care combina tot ce s-a prezentat mai sus: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## Metrici de urmarit449450Cum stii daca programul tau DevSecOps functioneaza? Urmareste aceste metrici:451452- **Mean time to remediate (MTTR)**: cat de repede remediezi vulnerabilitatile dupa detectare453- **Vulnerability escape rate**: procentul de vulnerabilitati care ajung in productie454- **False positive rate**: prea multe false pozitive duc la oboseala de alerte si avertismente ignorate455- **Dependency freshness**: varsta medie a dependentelor tale (mai vechi = mai probabil sa aiba CVE-uri cunoscute)456- **SBOM coverage**: procentul de proiecte cu SBOM-uri actualizate457458## Pentru a incepe: o foaie de parcurs practica459460Nu incerca sa implementezi totul dintr-o data. O abordare treptata functioneaza mai bine: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## Concluzie486487DevSecOps nu inseamna sa adaugi mai multe instrumente la pipeline-ul tau - inseamna sa faci din securitate o parte naturala a modului in care construiesti software. Scopul nu este sa blochezi fiecare PR cu avertismente de securitate, ci sa le oferi dezvoltatorilor feedback rapid pentru a putea corecta problemele cat timp codul este inca proaspat in mintea lor.488489Incepe cu bazele: pre-commit hooks pentru secrets, dependency scanning in CI si container scanning pentru imaginile Docker. Apoi itereaza in functie de nevoile echipei tale.490491Securitatea nu este o functionalitate pe care o livrezi o singura data. Este o practica pe care o integrezi in fiecare commit.492493> **Checklist de pornire DevSecOps:**494>495> - [x] Pre-commit hooks Gitleaks instalate496> - [x] Fisiere .env si secrets in .gitignore497> - [x] Semgrep SAST in pipeline-ul CI498> - [x] Snyk sau npm audit pentru dependency scanning499> - [x] Trivy pentru scanarea imaginilor de containere500> - [x] Utilizator non-root in Dockerfiles501> - [x] Secrets in variabile de mediu sau secret manager502> - [x] Generare SBOM la fiecare release503> - [x] Cunoasterea OWASP Top 10 in toata echipa504
:DevSecOps pentru dezvoltatori: un ghid practic de shift-left securitylines 1-504 (END) — press q to close