06 - Bezpieczeństwo łańcucha dostaw: audyt npm, SBOM i zarządzanie zależnościami
Wrzesień 2025 był punktem zwrotnym w historii bezpieczeństwa oprogramowania: osiemnaście pakietów npm wśród najczęściej pobieranych na świecie, w tym kreda, odpluskwić e style ansi, zostały naruszone w wyniku kampanii phishingowej skierowanej do opiekunów. W ciągu zaledwie kilku godzin ponad 2,6 miliarda pobrań tygodniowo jest poddawanych działaniu kodu JavaScript zaciemnione, mające na celu przechwytywanie transakcji kryptowalutowych. To nie jest atak do Twojej aplikacji, ale do ekosystemu, który ją obsługuje.
Ten scenariusz ilustruje fundamentalną naturę ataków na łańcuch dostaw: ich celem nie jest
kod, który piszesz, ale kod, któremu ufasz. Każda zależność, z którą instalujesz
npm install reprezentuje kod napisany przez innych, utrzymywany przez innych i potencjalnie
skompromitowany przez innych. W średniej wielkości projekcie Node.js bezpośrednie zależności to:
zazwyczaj 20-50 pakietów, ale może osiągnąć pełny wykres zależności przechodnich
łatwo 500-1000 bibliotek. Czy naprawdę sprawdzasz cały ten kod?
Według OWASP Top 10:2025 kategoria A03: Awarie oprogramowania i integralności danych wyraźnie uwzględnia awarie łańcucha dostaw jako wektor krytyczny. To jest jeden z dwóch nowe kategorie wprowadzone w edycji 2025, jednoznaczne uznanie, że bezpieczeństwo kod nie może już ignorować bezpieczeństwa zależności. W tym artykule znajdziesz konkretne narzędzia, które Cię ochronią.
Czego się nauczysz
- Anatomia ataku na łańcuch dostaw: literówka, zamieszanie zależności, zatrucie pliku blokującego
- Audyt npm, audyt przędzy, audyt pnpm: zaawansowane wykorzystanie i automatyzacja
- Integralność pliku blokady i weryfikacja skrótu za pomocą npm ci
- SBOM: generacja z CycloneDX i SPDX, standard NTIA
- Snyk i Depabot: Ciągłe monitorowanie luk w zabezpieczeniach
- Utwardzanie akcji GitHub: przypinanie SHA i minimalne uprawnienia
- Bezpieczeństwo obrazu kontenera: Trivy, Syft i podpisz w Cosign/Sigstore
- Zamieszanie zależności i sposób obrony przed prywatnymi zakresami npm
Anatomia ataku na łańcuch dostaw
Zrozumienie, jak działają ataki na łańcuch dostaw, jest pierwszym krokiem do obrony. Istnieje kilka głównych kategorii, każda z odmiennymi cechami i wektorami ataku.
Liposquatting: niebezpieczeństwo literówki
Typosquatting wykorzystuje typowe błędy w pisaniu. Osoba atakująca publikuje
lodahs (zamiast lodash), requst (zamiast
request), Lub colerrs (zamiast colors). W 2025 r.
Badacze zajmujący się bezpieczeństwem zidentyfikowali zestaw typowo zmodyfikowanych pakietów, które mają na celu
naśladują popularne biblioteki, które uruchamiają ukryte terminale za pomocą skryptów postinstall
aby po cichu wydobywać dane uwierzytelniające.
Główną obroną jest dokładne sprawdzenie nazwy przed zainstalowaniem jakiegokolwiek pakietu. Narzędzia takie jak Snyk i Socket.dev automatycznie analizują nazwy pod kątem podobieństwa istniejących pakietów i zgłoś potencjalne literówki przed instalacją.
Zamieszanie zależności: zakres publiczny vs prywatny
Zamieszanie zależności (lub pomieszanie przestrzeni nazw) jest udokumentowanym bardziej wyrafinowanym atakiem po raz pierwszy przez Alexa Birsana w 2021 r. Osoba atakująca publikuje pakiet na npm o tej samej nazwie, co prywatny pakiet wewnętrzny docelowej firmy, ale z liczbą wyższa wersja. npm domyślnie rozwiązuje najnowszą wersję z rejestru publicznego, prowadząc złośliwy pakiet do zastąpienia legalnego pakietu.
Prawdziwy przypadek: zamieszanie w zależnościach na dużą skalę
W 2021 roku Alex Birsan naraził na szwank ponad 35 dużych firm, w tym Microsoft, Apple i PayPal i Shopify korzystają z tej techniki, zarabiając ponad 130 000 dolarów w nagrodach za błędy. Mechanizm był prosty: znajdź wewnętrzne nazwy pakietów w plikach konfiguracyjnych public (package.json, pyproject.toml) i opublikuj je w wersji 9.9.9 w rejestrach publicznych.
Przejęcie konta opiekuna
Najbardziej podstępny atak z 2025 r. pokazał, jak ukierunkowany jest phishing na opiekunów stał się preferowanym przewoźnikiem. Gdy konto legalnego opiekuna zostanie naruszone, osoba atakująca publikuje złośliwe wersje już zaufanych pakietów. Społeczność ufa pakietu, testy bezpieczeństwa przechodzą pomyślnie i szkodliwy kod trafia do produkcji.
Zatrucie pliku blokady
W przypadku ataku polegającego na zatruwaniu pliku blokującego złośliwy współtwórca bezpośrednio modyfikuje plik
package-lock.json o yarn.lock w żądaniu ściągnięcia, na które należy wskazać
skompromitowane wersje lub skróty różniące się od oczekiwanych. Jeśli proces przeglądu nie obejmuje
sprawdzając plik blokujący, złośliwy kod pozostaje niezauważony.
Kontrola npm: Zaawansowane użycie
npm audit i punktem wyjścia, ale jego prawidłowe użycie wymaga czegoś więcej
proste wykonanie. Zobaczmy, jak skutecznie zintegrować go z przepływem prac programistycznych.
# 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'
W przypadku projektu z wieloma zależnościami liczba luk może być duża i
trudne do opanowania. Skuteczną strategią jest skonfigurowanie pliku .npmrc
z zasadami audytu projektu lub użyj npm audit z plikiem
konfiguracja wyjątku.
# .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"
}
}
Audyt pnpm i audyt przędzy
Jeśli używasz pnpm lub przędzy, polecenia kontroli są podobne, ale z pewnymi istotnymi różnicami. pnpm oferuje bardziej szczegółową kontrolę nad zależnościami, podczas gdy przędza v2/v3 (Berry) to robi znacznie ulepszone zarządzanie skrótami.
# 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'
Integralność pliku blokady: pierwsza linia obrony
Plik blokady (package-lock.json, yarn.lock, pnpm-lock.yaml)
i ma kluczowe znaczenie dla powtarzalności i bezpieczeństwa kompilacji. Każdy wpis w pliku blokady
zawiera nie tylko dokładną wersję, ale także skrót zawartości pakietu.
npm ci vs npm install: krytyczne rozróżnienie
W produkcji i CI/CD zawsze używaj npm ci zamiast npm install.
npm ci zainstaluj dokładnie te wersje określone w pliku blokującym, sprawdź
kryptograficzne skróty każdego pakietu i kończy się niepowodzeniem, jeśli plik blokujący nie jest zsynchronizowany
pakiet.json. npm install może zaktualizować plik blokady w trybie cichym.
# 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
Konfiguracja .npmrc dla zabezpieczeń
Plik .npmrc umożliwia skonfigurowanie npm z politykami bezpieczeństwa, które Ty
dotyczy całego projektu lub bieżącego użytkownika.
# .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/
Zamieszanie zależności: obrona za pomocą zakresów prywatnych
Najskuteczniejszą obroną przed pomieszaniem zależności jest zapewnienie, że pakiety są prywatne zawsze używaj dedykowanego zakresu i ten npm jest skonfigurowany do rozpoznawania tego zakresu wyłącznie z rejestru wewnętrznego.
# 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: zestawienie materiałów oprogramowania
Zestawienie materiałów oprogramowania (SBOM) i kompletny, formalny wykaz wszystkich komponentów oprogramowanie w aplikacji: biblioteki innych firm, zależności przechodnie, wersje, licencje i znane luki. Stało się to de facto wymogiem bezpieczeństwa przedsiębiorstwa, a w niektórych sektorach (rząd USA, infrastruktura krytyczna) jest to wymagane przez prawo.
Dwa główne standardy to SPDX (Wymiana danych pakietów oprogramowania, Linux Foundation) tj CyklonDX (OWASP). SPDX jest zorientowany na zgodność z licencjami, CycloneDX jest zoptymalizowany pod kątem zarządzania bezpieczeństwem i lukami w zabezpieczeniach. W przypadku aplikacji internetowych, CycloneDX jest ogólnie najlepszym wyborem.
Dlaczego SBOM jest ważny
Projekty wykorzystujące SBOM do zarządzania zależnościami osiągają redukcję o 264 dni średni czas do usunięcia (MTTR) w przypadku krytycznych luk w zabezpieczeniach w porównaniu z lukami bez SBOM. W przypadku nowego CVE (takiego jak Log4Shell) SBOM umożliwia identyfikację w ciągu kilku minut wszystkich projektów, których to dotyczy, zamiast tygodni ręcznej analizy.
Generowanie SBOM za pomocą 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" } }]
# }
# ]
# }
Generowanie SBOM za pomocą Syft
Syft firmy Anchore to jedno z najbardziej kompletnych narzędzi do generowania SBOM-ów obsługa obrazów kontenerów, systemów plików i artefaktów 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 i Depabot: Ciągłe monitorowanie
Jednorazowe monitorowanie nie wystarczy: odkrywane są nowe luki każdego dnia. Snyk i GitHub Depabot oferują ciągłe monitorowanie z automatycznymi alertami i aktualizuj żądania ściągnięcia.
Snyk CLI i integracja
# 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 Depabot: optymalna konfiguracja
# .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"
Bezpieczeństwo akcji GitHub: przypinanie i wzmacnianie SHA
Akcje GitHub reprezentują krytyczny wektor ataku w łańcuchu dostaw.
W 2024 r. kompromis ws tj-actions/changed-files pokazał jak
szeroko stosowana akcja może zostać naruszona i wykorzystana do wydobycia sekretów
tysiące repozytoriów. Główna obrona i przypinanie SHA: zamiast odwoływania się
jedna akcja na tag (@v4), używany jest niezmienny skrót zatwierdzenia.
# .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: Nigdy nie używaj tagów w akcjach stron trzecich
uses: some-org/some-action@v2 i podatne na ataki: jeśli konto opiekuna
zostanie naruszony, tag można zaktualizować tak, aby wskazywał złośliwy kod.
Zawsze używaj formatu uses: some-org/some-action@SHA_HASH # v2.0.0
i dołącz tag jako komentarz dla czytelności. Narzędzia takie jak
pinact e action-pins zautomatyzować ten proces.
Minimalne uprawnienia w przepływie pracy
# 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
Bezpieczeństwo obrazu kontenera
Jeśli aplikacja jest wdrożona w kontenerach platformy Docker, powierzchnia ataku zawiera także obraz podstawowy i zainstalowane pakiety systemu operacyjnego. Trivy i Grype to główne narzędzia do skanowania podatności w obrazach kontenerów.
# 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"
Lista kontrolna Angular: Bezpieczeństwo łańcucha dostaw
W przypadku projektów Angular istnieją szczególne uwagi dotyczące łańcucha narzędzi (Angular CLI, webpack/esbuild, ng-packagr) i ekosystem 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();
# });
Kompletny przepływ pracy: Brama bezpieczeństwa w CI/CD
Integracja wszystkich tych narzędzi w spójną bramkę bezpieczeństwa gwarantuje, że żadne kompilacja trafia do produkcji bez przejścia kontroli bezpieczeństwa łańcucha dostaw.
# .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
}
Cytat dotyczący wykrywania literówek
Przed zainstalowaniem nowego pakietu dobrą praktyką jest przetestowanie go za pomocą narzędzi dedykowanych analiz. Socket.dev to jedno z najlepszych narzędzi do analizy bezpieczeństwa pakietu npm przed instalacją.
# 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
Czerwone flagi w pakietach npm
- Skrypt poinstalacyjny: Uruchom kod po instalacji
- Dostęp do zmiennych środowiskowych:
process.envw pakiecie, który nie powinien tego potrzebować - Żądania HTTP do nieznanych domen: Żaden pakiet interfejsu użytkownika nie powinien wykonywać połączeń sieciowych w czasie instalacji
- Zależności natywne (powiązania): Skompiluj kod C/C++ z dostępem do systemu
- Wersja 0.0.1 z 10 milionami pobrań: niemożliwe, sygnał manipulacji statystycznej
- Nazwa podobna do znanych opakowań: Zawsze sprawdź npm.im przed instalacją
Wnioski i dalsze kroki
Bezpieczeństwo łańcucha dostaw nie jest działaniem jednorazowym, ale procesem ciągłym. 2025 wykazało, że nawet najbardziej zaufane pakiety mogą zostać naruszone i że obrona musi być wielowarstwowa: weryfikacja pliku blokującego, automatyczne audyty, wygenerowane SBOM przy każdym wydaniu, akcje GitHub z przypinaniem SHA i ciągłe monitorowanie za pomocą Snyk lub Depabot.
Zacznij od najprostszych kroków: dodaj npm audit --audit-level=high do twojego
CI/CD, zawsze używaj npm ci zamiast npm install w rurociągach,
i włącz Zależnego robota w swoim repozytorium. Te trzy zmiany obejmują większość
wektorów ataku przy minimalnej inwestycji czasu.
Następnym krokiem jest wygenerowanie SBOM przy każdym wydaniu i wdrożeniu kompletną bramkę bezpieczeństwa, taką jak ta pokazana w tym artykule. Z zasilaniem OWASP A03 Chain Failures teraz oficjalnie w Top 10 2025, to już nie jest miło mieć: i odpowiedzialność zawodowa każdego programisty.
Seria trwa: Bezpieczeństwo sieciowe dla programistów
- 01 - 10 najlepszych OWASP 2025: Przewodnik dla programistów
- 02 - XSS, CSRF i CSP: Bezpieczeństwo frontonu
- 03 — Wstrzykiwanie SQL i sprawdzanie poprawności danych wejściowych: Bezpieczeństwo zaplecza
- 04 - Bezpieczne uwierzytelnianie: sesja i pliki cookie
- 05 - Bezpieczeństwo API: OAuth 2.1, JWT i ograniczanie szybkości
- 06 - Bezpieczeństwo łańcucha dostaw: audyt npm i SBOM (ten artykuł)
- 07 - Błędy kryptograficzne: haszowanie, szyfrowanie i token
- 08 - DevSecOps dla programisty: SAST, DAST w CI/CD
Dowiedz się także więcej o serialu Interfejs DevOps (identyfikatory 250-255) aby zintegrować zabezpieczenia z procesem wdrażania.







