06 - Zabezpečení dodavatelského řetězce: audit npm, SBOM a Správa závislostí
Září 2025 znamenalo zlom v historii zabezpečení softwaru: osmnáct balíčků npm mezi nejstahovanější na světě, včetně křída, ladit e ansi-styly, jsou kompromitovány prostřednictvím phishingové kampaně zaměřené na správce. Během několika hodin je více než 2,6 miliardy stažení týdně vystaveno kódu JavaScript obfuscated navržený k zachycení transakcí kryptoměn. To není útok k vaší aplikaci, ale k ekosystému, který ji podporuje.
Tento scénář ilustruje základní povahu útoků na dodavatelský řetězec: nejsou zaměřeny
kód, který píšete, ale kód, kterému důvěřujete. Každá závislost, se kterou instalujete
npm install představuje kód napsaný ostatními, udržovaný ostatními a potenciálně
kompromitován ostatními. Ve středně velkém projektu Node.js jsou přímé závislosti
typicky 20-50 paketů, ale může dosáhnout graf plné tranzitivní závislosti
snadno 500-1000 knihoven. Opravdu kontrolujete celý tento kód?
Podle OWASP Top 10:2025 kategorie A03: Selhání integrity softwaru a dat výslovně zahrnuje selhání dodavatelského řetězce jako kritický vektor. Toto je jeden ze dvou nové kategorie zavedené ve verzi 2025, výslovné uznání, že bezpečnost kód již nemůže ignorovat bezpečnost závislostí. Tento článek vám poskytuje konkrétní nástroje, které vás ochrání.
Co se naučíte
- Anatomie útoku dodavatelského řetězce: překlepy, zmatení závislostí, otrava zámkovými soubory
- npm audit, yarn audit, pnpm audit: pokročilé použití a automatizace
- Integrita lockfile a ověření hash pomocí npm ci
- SBOM: generace s CycloneDX a SPDX, standard NTIA
- Snyk a Dependabot: Průběžné sledování zranitelnosti
- Posílení akcí GitHub: Připnutí SHA a minimální oprávnění
- Zabezpečení obrazu kontejneru: Trivy, Syft a podpis s Cosign/Sigstore
- Zmatek v závislosti a jak se bránit proti soukromým rozsahům npm
Anatomie útoku dodavatelského řetězce
Pochopení toho, jak fungují útoky na dodavatelský řetězec, je prvním krokem k obraně. Existuje několik hlavních kategorií, z nichž každá má odlišné vlastnosti a vektory útoku.
Typosquatting: nebezpečí překlepu
Typosquatting využívá běžné překlepy. Útočník publikuje
lodahs (místo lodash), requst (místo
request), nebo colerrs (místo colors). v roce 2025
Bezpečnostní výzkumníci identifikovali sadu překlepů vytvořených balíčků
napodobují oblíbené knihovny, které spouštěly skryté terminály prostřednictvím skriptů postinstall
k tichému úniku přihlašovacích údajů.
Hlavní obranou je důkladné ověření názvu před instalací jakéhokoli balíčku. Nástroje jako Snyk a Socket.dev automaticky analyzují podobnosti jmen existující balíčky a nahlásit potenciální překlepy před instalací.
Záměna závislostí: veřejný vs soukromý rozsah
Záměna závislostí (nebo záměna jmenného prostoru) je sofistikovanější útok zdokumentovaný pro poprvé od Alexe Birsana v roce 2021. Útočník publikuje balíček na npm se stejným názvem jako soukromý interní balíček cílové společnosti, ale s řadou vyšší verze. npm ve výchozím nastavení řeší nejnovější verzi z veřejného registru, vést škodlivý balíček k nahrazení legitimního balíčku.
Skutečný případ: Závislost ve velkém měřítku
V roce 2021 Alex Birsan kompromitoval více než 35 velkých společností včetně Microsoftu, Apple a PayPal a Shopify pomocí této techniky a vydělávají více než 130 000 $ na odměnách za chyby. Mechanismus byl jednoduchý: najít interní názvy balíčků v konfiguračních souborech public (package.json, pyproject.toml) a publikovat je s verzí 9.9.9 do veřejných registrů.
Převzetí účtu správce
Nejzákeřnější útok z roku 2025 ukázal, jak je phishing cílený na správce se stal preferovaným dopravcem. Jakmile dojde ke kompromitaci účtu legitimního správce, útočník publikuje škodlivé verze již důvěryhodných balíčků. Komunita důvěřuje balíčku, projdou bezpečnostní testy a škodlivý kód se dostane do výroby.
Lockfile Poisoning
Při útoku otravy lockfile škodlivý přispěvatel přímo upraví soubor
package-lock.json o yarn.lock v požadavku na vytažení, na který má ukázat
kompromitované verze nebo hodnoty hash odlišné od očekávaných. Pokud proces přezkoumání nezahrnuje
při kontrole lockfile zůstane škodlivý kód bez povšimnutí.
npm audit: Pokročilé použití
npm audit a výchozí bod, ale jeho správné použití vyžaduje více než
jednoduché provedení. Podívejme se, jak jej efektivně integrovat do pracovního postupu vývoje.
# Audit base con output JSON per processing automatico
npm audit --json
# Audit solo production dependencies (esclude devDependencies)
npm audit --omit=dev
# Fissa automaticamente le vulnerabilità patchabili
npm audit fix
# Fix anche di breaking changes (usare con cautela)
npm audit fix --force
# Audit con soglia di severita: exit code 1 se ci sono critical
npm audit --audit-level=critical
# Audit con soglia moderate
npm audit --audit-level=moderate
# Output in formato per CI/CD
npm audit --json | jq '.metadata.vulnerabilities'
U projektu s mnoha závislostmi může být počet zranitelností velký a
obtížné zvládnout. Účinnou strategií je konfigurace souboru .npmrc
se zásadami auditu projektu nebo použití npm audit se souborem
konfigurace výjimky.
# .nsprc (Node Security Project configuration)
# Oppure usa audit-resolve.json con npm-audit-resolver
# Installazione di npm-audit-resolver per gestire eccezioni
npm install -g npm-audit-resolver
# Processo interattivo per gestire ogni vulnerabilità
audit-resolve
# Verifica successiva (usa le eccezioni salvate)
audit-resolve --ci
# Script package.json per CI sicuro
# package.json
{
"scripts": {
"audit:ci": "npm audit --audit-level=high --omit=dev",
"audit:full": "npm audit --json > audit-report.json",
"audit:check": "npm audit --audit-level=critical"
}
}
audit pnpm a audit příze
Pokud používáte pnpm nebo yarn, jsou příkazy auditu podobné, ale s některými důležitými rozdíly. pnpm nabízí podrobnější kontrolu nad závislostmi, zatímco příze v2/v3 (Berry) ano výrazně vylepšený hash management.
# pnpm audit
pnpm audit
pnpm audit --audit-level high
pnpm audit --prod # solo production
# yarn audit (classic v1)
yarn audit
yarn audit --level high
# yarn audit (Berry v2/v3)
yarn npm audit
yarn npm audit --severity high
# Output JSON per processing
pnpm audit --json | jq '.advisories | length'
Integrita Lockfile: První linie obrany
Soubor zámku (package-lock.json, yarn.lock, pnpm-lock.yaml)
a zásadní pro reprodukovatelnost a bezpečnost sestavení. Každý záznam v lockfile
obsahuje nejen přesnou verzi, ale také hash obsahu balíčku.
Instalace npm ci vs npm: kritický rozdíl
Ve výrobě a CI/CD vždy používejte npm ci místo npm install.
npm ci nainstalujte přesně verze uvedené v lockfile, zkontrolujte
kryptografických hashů každého paketu a selže, pokud je lockfile nesynchronizovaný s
balíček.json. npm install může aktualizovat lockfile tiše.
# CORRETTO per CI/CD: verifica integrita lockfile
npm ci
# Verifica manuale degli hash nel lockfile
# package-lock.json contiene entries come:
# "node_modules/lodash": {
# "version": "4.17.21",
# "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
# "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZboqV76wE2wDvQ6",
# }
# Verifica che il lockfile non sia stato modificato
git diff package-lock.json | head -50
# Pre-commit hook per prevenire modifiche non autorizzate al lockfile
# .husky/pre-commit
#!/bin/sh
if git diff --cached --name-only | grep -q "package-lock.json"; then
echo "WARNING: package-lock.json modificato. Verifica le dipendenze."
npm audit --audit-level=high
fi
Konfigurace .npmrc pro zabezpečení
Soubor .npmrc umožňuje konfigurovat npm s bezpečnostními zásadami, které vy
platí pro celý projekt nebo pro aktuálního uživatele.
# .npmrc - configurazione sicurezza progetto
# Richiedi sempre HTTPS per il registro
registry=https://registry.npmjs.org/
# Abilita strict-ssl (default: true, non disabilitare mai!)
strict-ssl=true
# Audit automatico dopo ogni install
audit=true
# Fund messages: disabilita per CI
fund=false
# Usa lockfile (default: true)
package-lock=true
# Per workspace con pacchetti privati su registro Artifactory/Nexus
# @mycompany:registry=https://npm.mycompany.internal/
# //npm.mycompany.internal/:_authToken={NPM_TOKEN}
# Prevenzione dependency confusion: scope sempre sul registro privato
# @internal:registry=https://npm.internal.company.com/
Závislost Confusion: Obrana se pomocí Private Scopes
Nejúčinnější obranou proti záměně závislostí je zajistit, aby balíčky byly soukromé vždy používejte vyhrazený rozsah a že npm je nakonfigurován tak, aby vyřešil tento rozsah výhradně z interní evidence.
# package.json con scope privato corretto
{
"dependencies": {
"@mycompany/auth-utils": "^2.1.0",
"@mycompany/api-client": "^1.5.0"
}
}
# .npmrc - scope privati sempre sul registro interno
@mycompany:registry=https://npm.mycompany.internal/
//npm.mycompany.internal/:_authToken=${INTERNAL_NPM_TOKEN}
# Verifica che un pacchetto @mycompany NON esista su npm pubblico
npm view @mycompany/auth-utils --registry https://registry.npmjs.org/
# Deve restituire 404 - se restituisce un pacchetto, qualcuno ha fatto typosquatting!
# GitHub Actions: verifica automatica assenza pacchetti privati su npm pubblico
# - name: Check private packages not on public npm
# run: |
# for pkg in $(cat package.json | jq -r '.dependencies | keys[]' | grep "^@mycompany"); do
# if npm view $pkg --registry https://registry.npmjs.org/ 2>/dev/null; then
# echo "ALERT: $pkg trovato su npm pubblico!" && exit 1
# fi
# done
SBOM: Software kusovník
Software Bill of Materials (SBOM) a kompletní, formální inventář všech součástí software v aplikaci: knihovny třetích stran, přechodné závislosti, verze, licence a známé zranitelnosti. Stalo se de facto požadavkem na podnikové zabezpečení a v některých sektorech (vláda USA, kritická infrastruktura) je to vyžadováno zákonem.
Dvě hlavní normy jsou SPDX (Výměna dat softwarových balíčků, Linux Foundation) e CycloneDX (OWASP). SPDX je zaměřen na dodržování licencí, CycloneDX je optimalizován pro správu zabezpečení a zranitelnosti. Pro webové aplikace, CycloneDX je obecně nejlepší volba.
Proč je SBOM důležitý
Projekty využívající SBOM ke správě závislostí dosahují zkrácení 264 dní ve střední době nápravy (MTTR) pro kritická zranitelnost ve srovnání s těmi bez SBOM. V případě nového CVE (jako Log4Shell) umožňuje SBOM identifikaci během několika minut všechny dotčené projekty namísto týdnů ruční analýzy.
SBOM generace s CycloneDX
# Installazione CycloneDX CLI per Node.js
npm install -g @cyclonedx/cyclonedx-npm
# Generazione SBOM in formato JSON (CycloneDX v1.6)
cyclonedx-npm --output-format json --output-file sbom.json
# Generazione SBOM in formato XML
cyclonedx-npm --output-format xml --output-file sbom.xml
# Con dipendenze di sviluppo escluse
cyclonedx-npm --omit dev --output-format json --output-file sbom-prod.json
# Verifica del SBOM generato
cat sbom.json | jq '.metadata.component.name'
cat sbom.json | jq '.components | length'
cat sbom.json | jq '.vulnerabilities | length'
# Esempio output SBOM JSON (struttura CycloneDX v1.6)
# {
# "bomFormat": "CycloneDX",
# "specVersion": "1.6",
# "serialNumber": "urn:uuid:1a2b3c4d-...",
# "version": 1,
# "metadata": {
# "timestamp": "2026-02-25T10:30:00Z",
# "tools": [...],
# "component": {
# "type": "application",
# "name": "my-app",
# "version": "1.0.0"
# }
# },
# "components": [
# {
# "type": "library",
# "name": "express",
# "version": "4.18.2",
# "purl": "pkg:npm/express@4.18.2",
# "hashes": [
# { "alg": "SHA-256", "content": "abc123..." }
# ],
# "licenses": [{ "license": { "id": "MIT" } }]
# }
# ]
# }
SBOM generace se Syft
Syft by Anchore je jedním z nejúplnějších nástrojů pro generování SBOM, s podpora pro obrazy kontejnerů, souborové systémy a artefakty npm/pip/go/java.
# Installazione Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# SBOM da directory progetto (formato CycloneDX JSON)
syft dir:. -o cyclonedx-json=sbom.json
# SBOM da container image
syft nginx:latest -o spdx-json=sbom-nginx.json
# SBOM da immagine locale Docker
syft docker:my-app:latest -o cyclonedx-json=sbom.json
# Output in più formati simultaneamente
syft dir:. \
-o cyclonedx-json=sbom-cdx.json \
-o spdx-json=sbom-spdx.json \
-o table
# Filtrare solo componenti npm
syft dir:. -o cyclonedx-json | jq '.components[] | select(.purl | startswith("pkg:npm"))'
Snyk a Dependabot: Nepřetržité monitorování
Jednorázové monitorování nestačí: jsou objevena nová zranitelnost každý den. Snyk a GitHub Dependabot nabízejí nepřetržité monitorování s automatickými výstrahami a aktualizovat požadavky na stažení.
Snyk CLI a integrace
# Installazione Snyk CLI
npm install -g snyk
# Autenticazione
snyk auth
# Test vulnerabilità progetto
snyk test
# Test con soglia: exit 1 se vulnerabilità high/critical
snyk test --severity-threshold=high
# Monitor continuo (invia snapshot a Snyk dashboard)
snyk monitor
# Fix automatico con patch
snyk fix
# Generazione report HTML
snyk test --json | snyk-to-html -o report.html
# Test container image
snyk container test nginx:latest --severity-threshold=high
# Generazione SBOM via Snyk
snyk sbom --format cyclonedx1.6+json
# Integrazione in package.json
# {
# "scripts": {
# "security:test": "snyk test --severity-threshold=high",
# "security:monitor": "snyk monitor",
# "security:container": "snyk container test $IMAGE_NAME"
# }
# }
GitHub Dependabot: Optimální konfigurace
# .github/dependabot.yml
version: 2
updates:
# npm/Node.js dependencies
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
timezone: "Europe/Rome"
open-pull-requests-limit: 10
# Raggruppa aggiornamenti di patch e minor
groups:
production-dependencies:
dependency-type: "production"
update-types:
- "minor"
- "patch"
dev-dependencies:
dependency-type: "development"
update-types:
- "minor"
- "patch"
# Label automatiche per PR
labels:
- "dependencies"
- "security"
# Revisori automatici
reviewers:
- "security-team"
# Ignora major updates di alcune librerie critiche
ignore:
- dependency-name: "webpack"
update-types: ["version-update:semver-major"]
# GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
Zabezpečení akcí GitHub: SHA-Pinning a Hardening
Akce GitHub představují vektor kritického útoku na dodavatelský řetězec.
V roce 2024 bude kompromis tj-actions/changed-files předvedl jak
široce používaná akce může být kompromitována a použita k vyproštění tajemství
tisíce úložišť. Hlavní obrana a SHA-pinning: místo odkazování
jedna akce na značku (@v4), použije se neměnný hash odevzdání.
# .github/workflows/security-ci.yml
name: Security CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# Permissions minime (principio del minimo privilegio)
permissions:
contents: read
security-events: write # Per upload SARIF a GitHub Security tab
jobs:
dependency-audit:
name: Dependency Security Audit
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# SHA-pinned: usa hash commit, non tag!
# actions/checkout@v4 -> SHA esatto del commit
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '22'
cache: 'npm'
# Usa npm ci (non npm install) per verifica lockfile
- name: Install dependencies (strict lockfile)
run: npm ci --ignore-scripts
# Audit con exit code per bloccare la build
- name: npm audit
run: npm audit --audit-level=high --omit=dev
# Snyk test (richiede SNYK_TOKEN secret)
- name: Snyk Security Test
uses: snyk/actions/node@b98d498629f1c5e3943f89a5c62b5e5d4e2f86c0 # SHA pinned
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --fail-on=upgradable
sbom-generation:
name: Generate SBOM
runs-on: ubuntu-latest
needs: dependency-audit
permissions:
contents: write
id-token: write # Per OIDC (Sigstore)
attestations: write
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Node.js
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '22'
- name: Install dependencies
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.json
# Attesta il SBOM con OIDC (GitHub native attestation)
- name: Attest SBOM
uses: actions/attest-build-provenance@1c608d11d69870c2092266b3f9a6f3abbf17002c # v1.4.3
with:
subject-path: sbom.json
- name: Upload SBOM as artifact
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.0
with:
name: sbom
path: sbom.json
Anti-Pattern: Nikdy nepoužívejte značky v akcích třetích stran
uses: some-org/some-action@v2 a zranitelný: pokud je účet správce
je kompromitována, lze značku aktualizovat tak, aby ukazovala na škodlivý kód.
Vždy používejte formát uses: some-org/some-action@SHA_HASH # v2.0.0
a vložte značku jako komentář pro čitelnost. Nástroje jako
pinact e action-pins automatizovat tento proces.
Minimální oprávnění v pracovním postupu
# Imposta permissions di default a read-only per tutto il workflow
# SEMPRE aggiungere questo al livello top del workflow
permissions:
contents: read
# Poi concedi permissions aggiuntive solo ai job che le necessitano
jobs:
build:
permissions:
contents: read
packages: write # Solo se deve pubblicare su GitHub Packages
# Esempio job che NON ha bisogno di scrivere
test:
permissions:
contents: read # Solo lettura
# Variabili d'ambiente: mai hardcodare secrets
# SBAGLIATO:
# env:
# API_KEY: "sk-prod-abc123"
# CORRETTO: usa sempre GitHub Secrets
# env:
# API_KEY: ${{ secrets.API_KEY }}
# Limita anche GITHUB_TOKEN
# SBAGLIATO: permissions non specificati (default read+write)
# CORRETTO: specifica esplicitamente il minimo necessario
Zabezpečení obrazu kontejneru
Pokud je vaše aplikace nasazena v kontejnerech Docker, útok se vynoří zahrnuje také základní obraz a nainstalované balíčky OS. Trivy a Grype jsou hlavní nástroje pro skenování zranitelností v obrázcích kontejnerů.
# Installazione Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
# Scansione immagine locale
trivy image my-app:latest
# Solo vulnerabilità CRITICAL e HIGH
trivy image --severity HIGH,CRITICAL my-app:latest
# Output in formato SARIF per GitHub Security tab
trivy image --format sarif --output trivy-results.sarif my-app:latest
# Scansione del filesystem (anche senza Docker)
trivy fs --scanners vuln,secret,misconfig .
# Scansione con SBOM output
trivy image --format cyclonedx --output sbom.json my-app:latest
# Dockerfile best practices: usa immagini distroless
# FROM node:22-alpine AS builder
# WORKDIR /app
# COPY package*.json ./
# RUN npm ci --omit=dev
# COPY . .
# RUN npm run build
# Usa distroless come runtime (superficie minima di attacco)
# FROM gcr.io/distroless/nodejs22-debian12
# COPY --from=builder /app/dist /app
# EXPOSE 3000
# CMD ["/app/server.js"]
# Firma immagine con Cosign/Sigstore
cosign sign --yes my-registry/my-app:latest
# Verifica firma
cosign verify my-registry/my-app:latest --certificate-identity-regexp=".*" --certificate-oidc-issuer="https://accounts.google.com"
Úhlový kontrolní seznam: Zabezpečení dodavatelského řetězce
Pro projekty Angular existují specifické úvahy týkající se toolchainu (Angular CLI, webpack/esbuild, ng-packagr) a ekosystém npm.
# Angular Supply Chain Security Checklist
# 1. Verifica la versione di Angular CLI e dipendenze
ng version
npm audit
# 2. Aggiorna Angular alla versione LTS più recente
ng update @angular/core @angular/cli
# 3. Controlla i peer dependencies
npm ls --depth=0
# 4. Identifica dipendenze deprecate
npm outdated
# 5. Usa npm ci in tutti i CI/CD pipeline Angular
npm ci
# 6. Verifica integrità del lockfile prima di ogni build
git diff package-lock.json
# 7. Configura angular.json per production build con source-map disabilitato
# angular.json
# "configurations": {
# "production": {
# "sourceMap": false,
# "optimization": true,
# "buildOptimizer": true
# }
# }
# 8. Scansiona le dipendenze Angular specifiche
snyk test --file=package.json
# 9. Genera SBOM del progetto Angular
cyclonedx-npm --output-format json --output-file sbom-angular.json
# 10. Aggiungi Content-Security-Policy nel server Angular SSR
# Per Express server in server.ts:
# app.use((req, res, next) => {
# res.setHeader('Content-Security-Policy',
# "default-src 'self'; script-src 'self'");
# next();
# });
Kompletní pracovní postup: Bezpečnostní brána v CI/CD
Integrace všech těchto nástrojů do koherentní bezpečnostní brány zajišťuje, že žádný build dosáhne výroby, aniž by prošel bezpečnostními kontrolami dodavatelského řetězce.
# .github/workflows/supply-chain-security.yml
name: Supply Chain Security Gate
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
# Esegui ogni giorno alle 6:00 UTC per monitoraggio continuo
- cron: '0 6 * * *'
permissions:
contents: read
security-events: write
jobs:
security-gate:
name: Supply Chain Security Gate
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
node-version: '22'
cache: 'npm'
# Verifica integrita lockfile
- name: Verify lockfile integrity
run: |
if [ ! -f "package-lock.json" ]; then
echo "ERROR: package-lock.json mancante!" && exit 1
fi
npm ci --ignore-scripts
# Audit npm - blocca su HIGH/CRITICAL
- name: npm audit (production)
run: npm audit --audit-level=high --omit=dev
continue-on-error: false
# Snyk test
- name: Snyk vulnerability scan
uses: snyk/actions/node@b98d498629f1c5e3943f89a5c62b5e5d4e2f86c0
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --sarif-file-output=snyk.sarif
# Upload risultati a GitHub Security tab
- name: Upload Snyk results to GitHub Security
uses: github/codeql-action/upload-sarif@dd746615b1a4b1e1c5d3b87432fe040f4c04082 # v3.28.0
with:
sarif_file: snyk.sarif
# Genera SBOM
- name: Generate SBOM
run: |
npm install -g @cyclonedx/cyclonedx-npm
cyclonedx-npm --omit dev \
--output-format json \
--output-file sbom-${{ github.sha }}.json
# Salva SBOM come artifact
- name: Archive SBOM
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.0
with:
name: sbom-${{ github.sha }}
path: sbom-${{ github.sha }}.json
retention-days: 90
# License check
- name: Check licenses
run: |
npx license-checker --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD' \
--excludeDevDependencies \
--json > licenses.json || {
echo "ALERT: Licenze non conformi trovate!"
cat licenses.json
exit 1
}
Citace pro detekci překlepů
Před instalací jakéhokoli nového balíčku je dobré jej otestovat pomocí nástrojů specializovaných analýz. Socket.dev je jedním z nejlepších nástrojů pro analýzu zabezpečení balíčku npm před instalací.
# Socket.dev CLI per analisi preventiva
npm install -g @socketsecurity/cli
# Analizza un pacchetto prima di installarlo
socket npm info lodash
# Scansione del progetto esistente
socket scan create --view
# npm-check per pacchetti outdated e typosquatting
npm install -g npm-check
npm-check
# Verifica manuale: controlla chi ha pubblicato il pacchetto
npm view express maintainers
npm view express time # storia delle pubblicazioni
# Red flags da cercare:
# - Pacchetto pubblicato pochi giorni fa con molti download
# - Maintainer con storia breve
# - Nessuna homepage o repository
# - Scripts postinstall/preinstall sospetti
# Verifica scripts nel package.json della dipendenza
npm view lodash scripts
# Installa senza eseguire lifecycle scripts (postinstall, preinstall)
npm install --ignore-scripts
# Verifica il contenuto del pacchetto prima di usarlo
npm pack lodash --dry-run
Červené vlajky v balíčcích npm
- Skript po instalaci: Spustit kód při instalaci
- Přístup k proměnným prostředí:
process.envv balíčku, který by to neměl potřebovat - HTTP požadavky na neznámé domény: Žádný balíček uživatelského rozhraní by v době instalace neměl provádět síťová volání
- Nativní závislosti (vazby): Kompilace kódu C/C++ se systémovým přístupem
- Verze 0.0.1 s 10 miliony stažení: nemožné, statistický manipulační signál
- Název podobný slavným balíčkům: Před instalací vždy zkontrolujte npm.im
Závěry a další kroky
Zabezpečení dodavatelského řetězce není jednorázová činnost, ale trvalý proces. 2025 prokázal, že i ty nejdůvěryhodnější pakety mohou být kompromitovány a že obrana musí být vrstvená: ověřování lockfile, automatické audity, generované SBOM s každým vydáním, akce GitHub s připínáním SHA a nepřetržité monitorování pomocí Snyk nebo Dependabot.
Začněte s nejjednoduššími kroky: přidejte npm audit --audit-level=high k tvému
CI/CD, vždy používejte npm ci místo npm install v potrubích,
a povolte Dependabot ve vašem úložišti. Tyto tři změny pokrývají většinu
útočných vektorů s minimální časovou investicí.
Dalším krokem je vygenerování SBOM při každém vydání a implementaci kompletní bezpečnostní bránu, jako je ta uvedená v tomto článku. Se zdrojem OWASP A03 Selhání řetězu nyní oficiálně v Top 10 2025, to už není příjemné mít: a profesionální odpovědnost každého vývojáře.
Série pokračuje: 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 (tento článek)
- 07 - Kryptografické chyby: hašování, šifrování a token
- 08 - DevSecOps pro vývojáře: SAST, DAST v CI/CD
Zjistěte také více o seriálu Frontend DevOps (ID 250–255) integrovat zabezpečení do pracovního postupu nasazení.







