08 – DevSecOps pro vývojáře: SAST, DAST a zabezpečení v kanálu CI/CD
V únoru 2024 bezpečnostní výzkumník ukázal, jak kompromis tj-actions/changed-files, akci GitHub, kterou používá více než 23 000 úložišť, umožnila exfiltraci tajemství z CI/CD kanálů tisíců organizací. Problém nebyl v kódu aplikace, nebyl v závislostech, byl v procesu sám: nástroj, který měl chránit software, se stal vektorem útoku.
Tento scénář odráží nepohodlnou pravdu: Většina týmů investuje do zabezpečení kódu aplikace, ale zanedbává zabezpečení infrastruktury CI/CD, která jej vytváří, testuje a distribuuje. DevSecOps není jen integrací některých skenovacích nástrojů do kanálu, ale zásadní změna přístupu: bezpečnost musí být nedílnou součástí každé fáze vývojového cyklu, nikoli poslední kontrola před vydáním.
Podle zprávy DORA 2025 týmy, které přijmou komplexní postupy DevSecOps, hlásí a Střední doba nápravy (MTTR) pro kritické zranitelnosti 4x kratší ve srovnání s týmy, které provádějí bezpečnostní testy pouze ve fázi přípravy nebo výroby. Náklady na oprava bezpečnostní chyby ve výrobě a v průměru 100krát vyšší než opravte to během vývoje: princip „shift-left“ má ekonomické opodstatnění solidní, stejně jako technické.
Co se naučíte
- Zabezpečení Shift-left: Integrujte zabezpečení od začátku vývojového cyklu
- SAST se Semgrep a CodeQL: statická analýza zdrojového kódu
- DAST s OWASP ZAP: Dynamické testování běžících aplikací
- SCA s Snyk a Trivy: Analýza složení softwaru pro závislosti
- Skenování tajemství pomocí Gitleaks a TruffleHog: předcházení úniku přihlašovacích údajů
- Zabezpečení IaC pomocí Checkov: skenování manifestů Terraform a Kubernetes
- Dokončete kanál akcí GitHub pomocí bezpečnostních bran
- Metriky a KPI pro měření vyspělosti DevSecOps
Zabezpečení Shift-Left: základní princip
Pojem „shift-left“ pochází z vizuální reprezentace vývojového cyklu jako čáry časová osa zleva (plánování, vývoj) doprava (testování, výroba). Přesuňte zabezpečení vlevo znamená přiblížení bezpečnostních kontrol co nejblíže okamžik, kdy je kód zapsán: v IDE vývojáře, v háku před potvrzením, v pull requesty, nejen v pracovním prostředí.
Úrovně zabezpečení směny doleva, od nejreaktivnějších po nejproaktivnější, jsou:
- Úroveň 0 - Výroba: skenování zranitelnosti pouze v prod. Pozdě, drahé.
- Úroveň 1 – inscenace/předprodukce: DAST v testovacím prostředí. Lepší, ale stále pomalé.
- Úroveň 2 - CI/CD potrubí: SAST, SCA, skenování tajemství při každém stisknutí. standardy DevSecOps.
- Úroveň 3 – Požadavek na stažení: automatická kontrola zabezpečení každého PR. Rychlé a kontextové.
- Úroveň 4 – Předběžně se zavázat: místní kontroly před potvrzením. Okamžitá zpětná vazba.
- Úroveň 5 - PZI: Bezpečnostní plugin v editoru (Snyk IDE, rozšíření CodeQL). V reálném čase.
Paradox 45 %.
Výzkumy Veracode a GitLab ukazují, že 45 % kódu generují nástroje AI (GitHub Copilot, Cursor, Claude Code) má chyby zabezpečení, které by selhaly základní bezpečnostní testy. Ne proto, že by umělá inteligence byla skutečně nebezpečná, ale proto, že se replikuje nezabezpečené kódové vzory přítomné v trénovacích datových sadách. To dělá ovládací prvky automatizované v CI/CD ještě důležitější v éře vibračního kódování a pomocí AI vývoj. Podívejte se na seriál Vibe kódování abyste se do tohoto tématu ponořili hlouběji.
SAST: Statické testování zabezpečení aplikací
SAST analyzuje zdrojový kód, bytecode nebo binární kód bez spuštění aplikace, hledání vzorů zranitelných kódů, chybných konfigurací a bezpečnostních anti-vzorů. Je to nejrychlejší ovládání (lze provést během sekund nebo minut) a lze jej integrovat přímo v IDE, v pre-commit hook a v potrubí CI/CD.
Hlavní výhody SAST oproti jiným přístupům jsou: Běží na zdrojovém kódu (nevyžaduje spuštěnou instanci aplikace), nejprve identifikuje zranitelnosti nasazení a dokáže analyzovat 100 % kódu, včetně zřídka prováděných cest kódu. Hlavní nevýhodou je falešná pozitivita, která vyžaduje proces třídění a ladění pravidel.
Semgrep: SAST Open Source a Fast
Semgrep je pravděpodobně nejpoužívanějším nástrojem SAST v open source ekosystému v roce 2025.
Jeho síla spočívá v jednoduché syntaxi pravidel (struktura téměř totožná s kódem
která analyzuje), v rychlosti provádění a v nativní podpoře pro TypeScript, JavaScript,
Python, Go, Java a mnoho dalších jazyků. Udržuje tisíce bezpečnostních pravidel v
oficiální registr semgrep.dev.
# Installazione Semgrep
pip install semgrep
# oppure con Homebrew
brew install semgrep
# Scansione base con ruleset OWASP
semgrep --config p/owasp-top-ten .
# Scansione con regole specifiche per JavaScript/TypeScript
semgrep --config p/javascript .
semgrep --config p/typescript .
# Regole per Angular/Node.js
semgrep --config p/nodejs-express-security .
semgrep --config p/jwt .
# Output in formato SARIF per GitHub Security tab
semgrep --config p/owasp-top-ten --sarif --output semgrep.sarif .
# Output JSON per processing automatico
semgrep --config p/owasp-top-ten --json --output semgrep.json .
# Escludi cartelle non rilevanti
semgrep --config p/owasp-top-ten \
--exclude="node_modules,dist,coverage,*.min.js" .
# Regola custom Semgrep per trovare JWT senza verifica della firma
# .semgrep/jwt-insecure.yaml
# rules:
# - id: jwt-decode-without-verify
# patterns:
# - pattern: jwt.decode($TOKEN, ...)
# - pattern-not: jwt.verify($TOKEN, ...)
# message: "Uso di jwt.decode senza verifica: usa jwt.verify"
# severity: ERROR
# languages: [javascript, typescript]
CodeQL: Hluboká sémantická analýza
CodeQL, vyvinutý GitHubem, provádí hlubší analýzu než Semgrep: staví databázi kódu a umožňuje vám psát dotazy v jazyce SQL, které chcete najít zranitelnost také prostřednictvím více úrovní volání funkcí (analýza skvrn). LinkedIn v únoru 2026 oznámil, že svým způsobem používá CodeQL i Semgrep doplňkové pro optimální pokrytí kódové základny. CodeQL je nativně integrován do GitHub Advanced Security a je k dispozici zdarma pro veřejná úložiště.
# .github/workflows/codeql.yml
name: CodeQL Security Analysis
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
# Analisi settimanale (domenica alle 2:00 UTC)
- cron: '0 2 * * 0'
permissions:
contents: read
security-events: write
actions: read
jobs:
codeql-analysis:
name: CodeQL Analysis
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: ['javascript-typescript']
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Initialize CodeQL
uses: github/codeql-action/init@dd746615b1a4b1e1c5d3b87432fe040f4c04082 # v3.28.0
with:
languages: {{ matrix.language }}
# Query suite: default, extended, security-extended
queries: security-extended
config: |
paths-ignore:
- node_modules
- dist
- '**/*.test.ts'
- '**/*.spec.ts'
- name: Autobuild
uses: github/codeql-action/autobuild@dd746615b1a4b1e1c5d3b87432fe040f4c04082 # v3.28.0
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@dd746615b1a4b1e1c5d3b87432fe040f4c04082 # v3.28.0
with:
category: "/language:{{ matrix.language }}"
upload: true
SAST: Falešné pozitivy a třídění
Hlavním problémem SAST je počet falešných poplachů: agresivní sada pravidel může generovat stovky zpráv pro každé potvrzení, což činí proces neudržitelným. Doporučená strategie je začít s profilem vysoké závažnosti (pouze KRITICKÝ/VYSOKÝ), upravte pravidla pro vaši konkrétní kódovou základnu a postupně je zvyšujte pokrytí, když se tým s nástrojem seznámí. Nikdy neblokujte stavbu pro LOW/MEDIUM bez zavedeného procesu třídění.
DAST: Dynamické testování zabezpečení aplikací
Zatímco SAST analyzuje kód, aniž by jej spouštěl, DAST testuje aplikaci při a in provedení, simulující skutečné útoky zvenčí, jak by to udělal útočník. DAST najde zranitelnosti, které SAST nevidí: problémy s konfigurací serveru, chování za běhu, zranitelnosti v rozhraních REST API a problémy s ověřováním objevují se pouze se skutečnými požadavky HTTP.
DAST je doplněk k SAST, nikoli náhrada: SAST najde 70–80 % zranitelností ve zdrojovém kódu DAST najde zbývajících 20-30%, které se objeví pouze za běhu. Pro jednoho úplné pokrytí, obojí je nutné.
OWASP ZAP: Standard DAST v ekosystému Open Source
OWASP ZAP (Zed Attack Proxy) je nejpoužívanějším nástrojem DAST ve světě open source s nativní integrace v akcích GitHub. Nabízí tři hlavní režimy pro CI/CD: základní skenování (pasivní, neinvazivní, ideální pro každé PR), úplné skenování (aktivní, používá skutečné útočné zatížení, pouze v izolovaných prostředích) e Skenování API (specializované na OpenAPI/Swagger, ideální pro mikroslužby).
# .github/workflows/dast-zap.yml
name: DAST Security Scan (OWASP ZAP)
on:
push:
branches: [main]
workflow_dispatch:
inputs:
target_url:
description: 'URL target per la scansione DAST'
required: true
default: 'https://staging.myapp.com'
permissions:
contents: read
issues: write # ZAP crea issues GitHub per le vulnerabilità trovate
jobs:
zap-baseline-scan:
name: OWASP ZAP Baseline Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# Baseline scan: scansione PASSIVA (non invia payload di attacco)
# Ideale per ogni PR/push - veloce e non invasivo
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.14.0
with:
target: 'https://staging.myapp.com'
rules_file_name: '.zap/rules.tsv'
fail_action: true
cmd_options: '-a -j -l WARN'
# Full scan: scansione ATTIVA (usa payload di attacco reali)
# Solo in ambienti di test isolati, mai in produzione!
# - name: ZAP Full Scan (staging only)
# uses: zaproxy/action-full-scan@v0.11.0
# with:
# target: 'https://staging-isolated.myapp.com'
# API Scan: specializzato per REST API con OpenAPI spec
# - name: ZAP API Scan
# uses: zaproxy/action-api-scan@v0.9.0
# with:
# target: 'https://api.staging.myapp.com/openapi.json'
- name: Upload ZAP Report
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.0
if: always()
with:
name: zap-report
path: report_html.html
# .zap/rules.tsv - personalizzazione regole ZAP
# ID ACTION PARAM
# 10015 WARN # Incomplete or No Cache-control Header Set
# 10038 IGNORE # CSP Header Not Set (gestito separatamente dal server)
# 10096 WARN # Timestamp Disclosure
# 40014 IGNORE # CSRF (se il token CSRF e implementato lato app)
U projektů Angular s SSR musí DAST běžet na dostupné instanci z potrubí. Efektivní strategie a nasazení v pomíjivém pracovním prostředí (například na Firebase Hosting Preview Channel) jako součást kanálu spusťte DAST a pokračujte v nasazení do produkce, pouze pokud DAST projde.
# Esempio: Deploy staging effimero + DAST in pipeline Angular
# .github/workflows/angular-devsecops.yml (estratto)
jobs:
deploy-staging:
runs-on: ubuntu-latest
outputs:
staging_url: {{ steps.deploy.outputs.details_url }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- run: npm ci --ignore-scripts
- run: npm run build --configuration=staging
- name: Deploy to Firebase Hosting preview channel
id: deploy
uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: {{ secrets.GITHUB_TOKEN }}
firebaseServiceAccount: {{ secrets.FIREBASE_SERVICE_ACCOUNT }}
channelId: staging-{{ github.run_id }}
expires: 1d
dast-scan:
needs: deploy-staging
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: ZAP Baseline Scan on ephemeral staging
uses: zaproxy/action-baseline@v0.14.0
with:
target: {{ needs.deploy-staging.outputs.staging_url }}
fail_action: true
rules_file_name: '.zap/rules.tsv'
SCA: Analýza složení softwaru
SCA (Software Composition Analysis) analyzuje závislosti aplikace na open source k identifikaci známých zranitelností (CVE), problémů s licencemi a zastaralých balíčků. Předchozí článek ze série ( Zabezpečení dodavatelského řetězce: audit npm a SBOM) podrobně pokrývá npm audit, Snyk, Dependabot a generování SBOM. V tomto V kontextu se zaměřujeme na Trivy, který nabízí skenování SCA i IaC v jednom nástroj, ideální pro sjednocená potrubí DevSecOps.
# Trivy: SCA + container + IaC in un unico tool
# Installazione
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh \
| sh -s -- -b /usr/local/bin
# Scansione dipendenze npm (SCA)
trivy fs --scanners vuln --pkg-types library .
# Solo vulnerabilità HIGH e CRITICAL (per security gate)
trivy fs --scanners vuln --severity HIGH,CRITICAL \
--pkg-types library --exit-code 1 .
# Output SARIF per GitHub Security tab
trivy fs --scanners vuln --format sarif \
--output trivy-results.sarif .
# Scansione con SBOM output (CycloneDX)
trivy fs --format cyclonedx --output sbom.json .
# File .trivyignore per CVE accettati (con motivazione obbligatoria!)
# .trivyignore
# CVE-2023-44270 # postcss: impatto solo in CLI, non nel build output - review 2026-06-01
# Scansione completa: vuln + segreti + misconfigurazioni
trivy fs --scanners vuln,secret,misconfig .
# GitHub Actions con Trivy Action ufficiale
# - name: Run Trivy vulnerability scanner
# uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
# with:
# scan-type: 'fs'
# scan-ref: '.'
# scanners: 'vuln,secret'
# severity: 'HIGH,CRITICAL'
# exit-code: '1'
# format: 'sarif'
# output: 'trivy-results.sarif'
Skenování tajemství: Prevence úniku pověření
Na veřejném GitHubu jsou každý týden náhodně odhaleny tisíce tajemství: Klíče API, tokeny OAuth, hesla k databázi, soukromé certifikáty. GitGuardian, který monitoruje veřejná úložiště, uvádí, že v roce 2024 jich bylo odhaleno přes 12 milionů tajemství vystavených na veřejných úložištích, s nárůstem o 28 % ve srovnání s rokem předchozí. Jakmile je tajemství ve veřejném úložišti (i na několik minut). před odstraněním), by měly být považovány za ohrožené a okamžitě otočit.
Gitleaks a TruffleHog jsou dva nejpoužívanější nástroje pro detekci tajemství s přístupy doplňkové: Gitleaks je rychlý a skvělý pro CI/CD, TruffleHog aktivně kontroluje zda jsou nalezená tajemství stále platná (významně snižuje počet falešných poplachů).
Gitleaks: Konfigurace a integrace
# Installazione Gitleaks
brew install gitleaks
# oppure scarica il binario da GitHub Releases
# https://github.com/gitleaks/gitleaks/releases
# Scansione del repository corrente (tutti i commit)
gitleaks detect --source . --verbose
# Scansione solo dei file staged (per pre-commit hook)
gitleaks protect --staged --verbose
# Scansione di un range di commit specifico
gitleaks detect --source . --log-opts HEAD~1..HEAD
# Output in formato JSON
gitleaks detect --source . --report-format json \
--report-path gitleaks-report.json
# Configurazione pre-commit con pre-commit framework
# .pre-commit-config.yaml
# repos:
# - repo: https://github.com/gitleaks/gitleaks
# rev: v8.24.2
# hooks:
# - id: gitleaks
# Configurazione custom .gitleaks.toml
# [extend]
# useDefault = true
#
# [[rules]]
# id = "internal-api-token"
# description = "Token API interno MyCompany"
# regex = '''mycompany_token_[0-9a-zA-Z]{32}'''
# tags = ["token", "internal"]
#
# [allowlist]
# description = "Test fixtures e placeholder sicuri"
# regexTarget = "line"
# regexes = [
# '''EXAMPLE_TOKEN_PLACEHOLDER''',
# '''test_secret_[a-z0-9]{8}'''
# ]
# paths = [
# '''.*_test\.ts''',
# '''.*\.spec\.ts''',
# '''.*\.fixture\.ts'''
# ]
TruffleHog: Aktivní tajné ověření
# Installazione TruffleHog
curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh \
| sh -s -- -b /usr/local/bin
# Scansione con verifica attiva (riduce falsi positivi)
trufflehog git file://. --only-verified
# Scansione di un repository remoto
trufflehog github --repo https://github.com/myorg/myrepo --only-verified
# Output JSON per processing
trufflehog git file://. --json --no-verification
# GitHub Actions: secrets scanning su ogni push/PR
# .github/workflows/secrets-scan.yml
# - name: TruffleHog secrets scan
# uses: trufflesecurity/trufflehog@main
# with:
# path: ./
# base: $GITHUB_BASE_REF
# head: HEAD
# extra_args: --only-verified
# Differenza chiave Gitleaks vs TruffleHog:
# - Gitleaks: veloce, pattern matching, ottimo per pre-commit e CI
# - TruffleHog: verifica attiva (testa il secret contro l'API reale)
# Risultato: meno falsi positivi, ma più lento e invasivo
# Raccomandazione: entrambi in pipeline (Gitleaks fast, TruffleHog verified)
Tajemství se neodstraňují pomocí git rm
Pokud dojde k omylu tajného klíče, odstraňte soubor s git rm nebo
přidat soubor do .gitignore nestačí: tajemství je stále
viditelné v historii git. Chcete-li to opravdu odstranit, použijte git filter-repo
(nástroj oficiálně doporučený GitHubem), poté vynucení zatlačení na všechny větve,
a považujte tajemství za kompromitované a okamžitě jej otočte. GitHub také nabízí
nativní nástroj "Tajné skenování" v nastavení úložiště, které sleduje
průběžně zadávat historii více než 200 známých typů tokenů.
Zabezpečení IaC: Checkov pro Terraform a Kubernetes
Infrastruktura jako kód (IaC) demokratizovala správu infrastruktury, ale ano také představil nový vektor rizika: nesprávné konfigurace v souborech Terraform, Kubernetes manifesty, Docker Compose a AWS CloudFormation, které mohou odhalit celou vaši infrastrukturu. Checkov (Bridgecrew/Palo Alto Networks) staticky skenuje tyto soubory s více než 1000 Integrovaná bezpečnostní politika, mapovaná na CIS Benchmarks, NIST a další standardy.
Poznámka: tfsec, originální IaC skenovací nástroj Aqua Security, byl integrován v Trivy. Pro nové projekty se doporučuje Trivy for IaC nebo Checkov pro širší pokrytí.
# Installazione Checkov
pip install checkov
# oppure con Homebrew
brew install checkov
# Scansione directory Terraform
checkov -d ./terraform
# Scansione Kubernetes manifests
checkov -d ./k8s --framework kubernetes
# Scansione Dockerfile
checkov -f Dockerfile --framework dockerfile
# Output in formato SARIF per GitHub Security
checkov -d ./terraform --output sarif --output-file checkov.sarif
# Skippa check specifici (con commento di motivazione!)
checkov -d ./terraform --skip-check CKV_AWS_18,CKV_AWS_21
# Violazioni Terraform AWS comuni che Checkov rileva:
# CKV_AWS_18: S3 bucket - access logging disabilitato
# CKV_AWS_57: S3 bucket - ACL pubblica (mai in produzione!)
# CKV_AWS_87: Lambda - non in VPC
# CKV_AWS_135: EC2 - IMDSv1 abilitato (usa IMDSv2)
# Esempio Kubernetes manifest INSICURO (violazioni Checkov):
# apiVersion: v1
# kind: Pod
# spec:
# containers:
# - name: app
# image: myapp:latest # CKV_K8S_14: usa tag specifico, non :latest
# securityContext:
# runAsRoot: true # CKV_K8S_6: non eseguire come root
# privileged: true # CKV_K8S_16: non usare privileged mode
# resources: {} # CKV_K8S_11: definisci resource limits
# Esempio Kubernetes manifest SICURO (supera Checkov):
# spec:
# containers:
# - name: app
# image: myapp:1.2.3
# securityContext:
# runAsNonRoot: true
# runAsUser: 1000
# allowPrivilegeEscalation: false
# readOnlyRootFilesystem: true
# resources:
# limits:
# memory: "256Mi"
# cpu: "500m"
# requests:
# memory: "128Mi"
# cpu: "250m"
GitHub Actions Pipeline Complete: The Ultimate Security Gate
Integrace všech těchto nástrojů do jednoho koherentního potrubí vyžaduje plánování buďte opatrní: ne všechny úlohy musí blokovat sestavení, některá skenování jsou vhodnější pro PR, zatímco ostatní pro push on main a paralelizace je zásadní pro non nadměrně zpomalit vývojový tok. Jeden z nich ilustruje následující potrubí kompletní konfigurace se 6 paralelními a sekvenčními úlohami.
# .github/workflows/devsecops-complete.yml
name: DevSecOps Security Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
schedule:
- cron: '0 3 * * 1' # Ogni lunedi alle 3:00 UTC (scan completo)
# Permissions minime a livello workflow (principio del minimo privilegio)
permissions:
contents: read
jobs:
# ===== JOB 1: SECRETS SCANNING (primo - fail fast) =====
secrets-scan:
name: Secrets Scanning
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0 # Storia completa per Gitleaks
- name: Gitleaks secrets detection
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: {{ secrets.GITHUB_TOKEN }}
# ===== JOB 2: SCA - Dependency Vulnerabilities =====
sca-scan:
name: SCA Dependency Audit
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '22'
cache: 'npm'
- run: npm ci --ignore-scripts
- name: npm audit (solo production deps)
run: npm audit --audit-level=high --omit=dev
- name: Trivy SCA scan
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
with:
scan-type: 'fs'
scan-ref: '.'
scanners: 'vuln'
severity: 'HIGH,CRITICAL'
exit-code: '1'
format: 'sarif'
output: 'trivy-vuln.sarif'
- name: Upload Trivy results
uses: github/codeql-action/upload-sarif@dd746615b1a4b1e1c5d3b87432fe040f4c04082
if: always()
with:
sarif_file: 'trivy-vuln.sarif'
# ===== JOB 3: SAST - Static Code Analysis =====
sast-scan:
name: SAST Static Analysis
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
actions: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Initialize CodeQL
uses: github/codeql-action/init@dd746615b1a4b1e1c5d3b87432fe040f4c04082
with:
languages: 'javascript-typescript'
queries: security-extended
- name: Autobuild
uses: github/codeql-action/autobuild@dd746615b1a4b1e1c5d3b87432fe040f4c04082
- name: CodeQL Analysis
uses: github/codeql-action/analyze@dd746615b1a4b1e1c5d3b87432fe040f4c04082
with:
category: "/language:javascript-typescript"
- name: Semgrep SAST
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/javascript
p/typescript
p/jwt
env:
SEMGREP_APP_TOKEN: {{ secrets.SEMGREP_APP_TOKEN }}
# ===== JOB 4: IaC Security =====
iac-scan:
name: IaC Security Scan
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Trivy config scan
uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca
with:
scan-type: 'config'
scan-ref: '.'
severity: 'HIGH,CRITICAL'
exit-code: '1'
- name: Checkov IaC scan
uses: bridgecrewio/checkov-action@v12
with:
directory: .
framework: all
soft_fail_on: MEDIUM
hard_fail_on: HIGH,CRITICAL
# ===== JOB 5: DAST (solo su push a main) =====
dast-scan:
name: DAST ZAP Baseline
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [secrets-scan, sca-scan, sast-scan]
permissions:
contents: read
issues: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: ZAP Baseline Scan
uses: zaproxy/action-baseline@v0.14.0
with:
target: {{ secrets.STAGING_URL }}
fail_action: true
- name: Upload ZAP Report
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
if: always()
with:
name: zap-report-{{ github.sha }}
path: report_html.html
retention-days: 30
# ===== JOB 6: SBOM (su push a main dopo tutti i check) =====
sbom-generate:
name: Generate SBOM
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
needs: [sca-scan, sast-scan, iac-scan]
permissions:
contents: write
id-token: write
attestations: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af
with:
node-version: '22'
- run: npm ci --ignore-scripts
- name: Generate SBOM (CycloneDX)
run: |
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --omit dev \
--output-format json \
--output-file sbom-{{ github.sha }}.json
- name: Attest SBOM
uses: actions/attest-build-provenance@v1
with:
subject-path: sbom-{{ github.sha }}.json
- name: Upload SBOM
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: sbom-{{ github.sha }}
path: sbom-{{ github.sha }}.json
retention-days: 365
Bezpečnostní brány: Co blokuje stavbu a co ne
Účinná bezpečnostní brána neblokuje každé varování, ale rozlišuje mezi problémy které vyžadují okamžitou pozornost a problémy, které lze časem zvládnout. Základní pravidlo zní: blokuje pouze to, co je zjevně nebezpečné a použitelné. Blokování sestavení pro příliš mnoho falešně pozitivních nebo NÍZKÝCH zranitelností vede tým k deaktivaci ovládání úplně, což zruinuje celou investici.
Bezpečnostní Gates Matrix doporučeno
- Vždy BLOKOVAT: Tajemství v kódu, KRITICKÉ zranitelnosti s opravou dostupné, SAST injection/RCE nálezy, IaC chybná konfigurace KRITICKÉ (Veřejný segment S3, skupina zabezpečení 0.0.0.0/0 ve vstupním SSH)
- BLOCK na hlavní (ne na PR): VYSOKÁ zranitelnost s dostupnou opravou, Nálezy DAST nastaveny na FAIL, závislosti s nekompatibilními licencemi (GPL in komerční produkt)
- VAROVÁNÍ (upozorňuje, ale neblokuje): VYSOKÁ zranitelnost bez opravy k dispozici, STŘEDNÍ v SAST, IaC HIGH s řešením dokumentovaným v výjimky, nálezy DAST nastaveny na WARN
- IGNOROVAT (s dokumentací): Zranitelnost LOW/INFO, falešné poplachy dokumentováno v souboru výjimek (.trivyignore, .gitleaks.toml seznam povolených), CVE bez skutečného dopadu na kontext konkrétní aplikace
# Gestione delle eccezioni documentate nei file di configurazione
# .trivyignore - CVE accettati con motivazione obbligatoria
# Formato: CVE-ID # [data] Motivazione e piano di revisione
CVE-2023-44270 # [2026-02-01] postcss: impatto solo in CLI usage, non nel build output. Review 2026-06
# .gitleaks.toml - allowlist per pattern non pericolosi
# [allowlist]
# description = "Test fixtures, placeholder e valori di esempio"
# regexes = [
# '''EXAMPLE_API_KEY_[A-Z0-9]{16}''',
# '''test_secret_placeholder''',
# '''YOUR_TOKEN_HERE'''
# ]
# paths = [
# '''.*\.spec\.ts''',
# '''.*\.fixture\.ts''',
# '''README\.md'''
# ]
# Semgrep - eccezione inline nel codice sorgente
# Aggiungi commento sulla stessa riga per sopprimere un finding
# const regex = new RegExp(userPattern); // nosemgrep: javascript.lang.security.audit.unsafe-regex
# Checkov - soppressione inline nel file Terraform
# resource "aws_s3_bucket" "cdn_assets" {
# bucket = "my-public-cdn-assets"
# #checkov:skip=CKV_AWS_57: Bucket CDN per assets statici pubblici - progettato per essere pubblico
# }
Úhlový kontrolní seznam: DevSecOps Pipeline
Úhlové projekty mají specifické úvahy týkající se DevSecOps toolchain (Angular CLI, esbuild, ng-packagr), k použití HTML šablon s vazbami dynamické a na SSR se serverem Node.js Express.
# Angular DevSecOps Checklist
# 1. SAST: regole Semgrep specifiche per Angular
# Patterns pericolosi da rilevare:
# - DomSanitizer.bypassSecurityTrustHtml(userInput) senza sanitizzazione
# - [innerHTML]="untrustedData" (binding HTML non sicuro)
# - eval() o new Function() in servizi Angular
# - HttpClient senza interceptor di autenticazione
# 2. SECRETS: environment files NON devono contenere valori reali
# SBAGLIATO - environment.ts committato con secret:
# export const environment = {
# apiKey: 'sk-prod-real-key-12345', # Bloccato da Gitleaks!
# googleMapsKey: 'AIza...' # Bloccato da Gitleaks!
# };
# CORRETTO - placeholder nei file committati, valori iniettati in CI:
# export const environment = {
# apiKey: '', // iniettato a build time dalla pipeline CI/CD
# };
# In pipeline: sed -i "s/apiKey: ''/apiKey: '{{ secrets.API_KEY }}'/" src/environments/environment.prod.ts
# 3. CSP HEADER nel server SSR Angular (Express)
# server.ts
# import { randomBytes } from 'crypto';
# const generateNonce = () => randomBytes(16).toString('base64');
#
# app.use((req, res, next) => {
# const nonce = generateNonce();
# res.locals['nonce'] = nonce;
# res.setHeader('Content-Security-Policy', [
# "default-src 'self'",
# `script-src 'self' 'nonce-${nonce}'`,
# "style-src 'self' 'unsafe-inline'",
# "img-src 'self' data: https:",
# "connect-src 'self' https://api.myapp.com",
# "frame-ancestors 'none'"
# ].join('; '));
# next();
# });
# 4. SAST Semgrep per Angular (regola custom bypassSecurityTrust)
# .semgrep/angular-security.yaml
# rules:
# - id: angular-bypass-security-trust
# patterns:
# - pattern: this.$SANITIZER.bypassSecurityTrust$TYPE(...)
# message: "Uso di bypassSecurityTrust$TYPE: verifica la sanitizzazione del valore"
# severity: WARNING
# languages: [typescript]
# 5. Verifica e aggiornamento Angular LTS
ng version
npm outdated @angular/core @angular/cli @angular/material
npm audit --omit=dev --audit-level=high
Metriky a KPI pro zralost DevSecOps
Pro zlepšení je nezbytné měření. Metriky DevSecOps musí být v rovnováze rychlost vývoje s účinností bezpečnosti. Cíl není nikdy nulový zranitelnosti (nedosažitelné), ale snížit riziko na přijatelnou úroveň v co nejkratším čase.
Základní KPI DevSecOps
- MTTD (střední doba do detekce): průměrná doba mezi zavedením jednoho zranitelnost a její odhalení. Cíl s CI/CD: méně než 24 hodin. S úplným posunem doleva (před potvrzením): detekce v sekundách.
- MTTR (střední doba do nápravy): od detekce po opravu ve výrobě. Cíl OWASP: méně než 7 dní pro KRITICKÉ, méně než 30 pro VYSOKÉ. S vyspělými procesy DevSecOps: MTTR 4x nižší než tradiční týmy.
- Poměr detekce Shift-Left (SLDR): procento zranitelnosti zjištěno ve vývoji vs. Cíl: Více než 80 % zjištěných před nasazením.
- zajišťovací dluh: celkový počet otevřených zranitelností podle závažnosti. Sledujte trend v průběhu času: musí se snížit nebo zůstat stabilní.
- Falešně pozitivní míra: procento falešně pozitivních výstrah SAST/DAST. Cíl: pod 20 %, aby nedošlo k únavě týmu a zachovala se důvěryhodnost procesu.
- Délka potrubí: celkový čas potrubí DevSecOps. Cíl: SAST + SCA + tajemství do 10 minut, aby nedošlo k ovlivnění produktivity.
- Bezpečnostní krytí: procento kódové základny pokryté SAST, Procento API pokryté DAST. Cíl: více než 90 % pro SAST.
# Script per generare un report KPI di sicurezza dal progetto
# Conta vulnerabilità aperte con npm audit
npm audit --json | jq '.metadata.vulnerabilities'
# Output: { "info": 2, "low": 5, "moderate": 3, "high": 1, "critical": 0, "total": 11 }
# Conta findings SAST da Semgrep (JSON output)
semgrep --config p/owasp-top-ten --json . 2>/dev/null \
| jq '.results | group_by(.extra.severity) | map({severity: .[0].extra.severity, count: length})'
# Verifica durata pipeline (GitHub Actions API)
curl -s -H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?per_page=10" \
| jq '[.workflow_runs[] | select(.name == "DevSecOps Security Pipeline") | {
run_id: .id,
status: .status,
conclusion: .conclusion,
duration_seconds: ((.updated_at | fromdateiso8601) - (.run_started_at | fromdateiso8601))
}]'
# Badge GitHub Actions per status sicurezza nel README
# 
Kultura DevSecOps: Lidský faktor
Samotná technologie nestačí: DevSecOps vyžaduje kulturní změnu který transformuje bezpečnost z odpovědnosti specializovaného týmu na odpovědnost sdílené všemi vývojáři. To vyžaduje školení, jasné procesy a především odstranění tření, která činí bezpečnost spíše vnímanou překážkou než překážkou kvalitní nástroj.
Základní principy vyspělé kultury DevSecOps jsou:
- "Zabezpečení jako kód": Security policies are code, versioned in git, reviewed like any other codebase change. Exceptions to the policies jsou zdokumentovány v samotném kódu, s odůvodněním a datem revize.
- Okamžitá a kontextová zpětná vazba: vývojář dostává zpětnou vazbu od zabezpečení v IDE nebo PR, ne o týdny později v nesrozumitelné zprávě ve formátu PDF. Kontext je zásadní: "tato funkce má problém s injekcí SQL na řádku 42" a mnohem užitečnější než "typ zranitelnosti A07 zjištěný v backendovém modulu".
- Žádná výčitka, ano učení: Chyby zabezpečení nalezené v CI/CD jsou možnosti učení, ne tresty. Vývojář, který je představil musí pochopit, proč a jak jim v budoucnu předcházet.
- Program bezpečnostního šampiona: každý tým má bezpečnostního šampiona, který funguje jako most mezi vývojovým a bezpečnostním týmem, provádí počáteční třídění výstrah a propaguje osvědčené postupy kontextovým způsobem.
- Preventivní modelování hrozeb: před implementací funkce, tým diskutuje o potenciálních vektorech útoku. STRIDE (spoofing, manipulace, Odmítnutí, zpřístupnění informací, DoS, zvýšení oprávnění) a rámec jednoduché a praktické pro tento proces.
Rychlé výhry pro začátek s DevSecOps ještě dnes
Pokud začínáte od nuly, nesnažte se implementovat vše najednou. Tady tři kroky, které pokryjí 80 % rizika s 20 % úsilí:
-
Přidejte Gitleaks k předběžnému závazku: nainstalovat rámec před potvrzením,
přidat konfiguraci Gitleaks
.pre-commit-config.yaml, běhatpre-commit install. Zabraňte úniku tajemství dříve, než se dostanou vzdálené úložiště. Předpokládaná doba: 30 minut. -
Povolte GitHub Dependabot a audit npm v CI: Aktivujte Dependabot v
nastavení úložiště a přidat
npm audit --audit-level=high --omit=devdo vašeho stávajícího potrubí CI. Dostávejte automatická upozornění na zranitelné závislosti. Odhadovaný čas: 1 hodina. - Povolte CodeQL na GitHubu: Zdarma pro veřejná úložiště, včetně v pokročilém zabezpečení GitHub pro podniková soukromá úložiště. Automatický SAST na každém požadavky push a pull bez nutnosti další konfigurace. Odhadovaný čas: 15 minut.
Závěry a další kroky
DevSecOps není produkt ke koupi ani nástroj k instalaci: je to proces neustálé zlepšování, které integruje bezpečnost, vývoj a operace v jednom cyklu ctnostný. Potrubí uvedené v tomto článku pokrývá všechny hlavní vrstvy: skenování tajemství, aby se zabránilo únikům pověření, SCA pro závislosti, SAST pro zdrojový kód, DAST pro běhové prostředí, zabezpečení IaC pro infrastrukturu, a generování SBOM pro sledovatelnost a shodu.
Hlavní princip je vždy stejný: najít problémy co nejdříve, kdy náklady na opravu jsou minimální. Se 45 % kódu generovaného umělou inteligencí selže i Základní bezpečnostní testování, automatizace DevSecOps se v éře stala ještě důležitější vývoj podporovaný umělou inteligencí. Nemůžeme se na to spolehnout pouze na ruční kontrolu v kontextu vysokorychlostního vývoje.
Tento článek uzavírá sérii Webová bezpečnost pro vývojáře: prošli jsme celý zásobník zabezpečení, od 10 nejlepších zranitelností OWASP k frontendové obraně, od zabezpečení backendu po šifrování až po DevSecOps jako lepidlo, které spojuje všechny osvědčené postupy v automatizovaném a měřitelném procesu. Zabezpečení není konečný produkt, ale nepřetržitá cesta: každá verze je příležitost ke zlepšení zabezpečení vašeho softwaru.
Celá řada: Zabezpečení webu pro vývojáře
- 01 – OWASP Top 10 2025: Průvodce pro vývojáře
- 02 - XSS, CSRF a CSP: Zabezpečení frontendu
- 03 - SQL Injection a Input Validation: Backend Security
- 04 - Bezpečná autentizace: relace a soubory cookie
- 05 - Zabezpečení API: OAuth 2.1, JWT a omezení rychlosti
- 06 - Zabezpečení dodavatelského řetězce: audit npm a SBOM
- 07 - Kryptografické chyby: hašování, šifrování a token
- 08 - DevSecOps pro vývojáře: SAST, DAST v CI/CD (tento článek)
Zjistěte také více o seriálu Frontend DevOps (ID 250–255) integrovat zabezpečení s pracovním postupem nasazení Angular a řadou Vibe kódování abyste pochopili rizika bezpečnostní problémy specifické pro kód generovaný AI a jak je zmírnit pomocí DevSecOps.







