06 - 공급망 보안: npm 감사, SBOM 및 종속성 관리
2025년 9월은 소프트웨어 보안 역사의 전환점이 되었습니다: 18개의 패키지 npm은 다음을 포함하여 세계에서 가장 많이 다운로드된 것 중 하나입니다. 분필, 디버그 e ANSI 스타일, 관리자를 대상으로 한 피싱 캠페인을 통해 손상되었습니다. 단 몇 시간 만에 매주 26억 건 이상의 다운로드가 JavaScript 코드에 노출됩니다. 암호화폐 거래를 가로채도록 설계된 난독화. 이건 공격이 아니야 귀하의 애플리케이션뿐만 아니라 이를 지원하는 생태계에도 적용됩니다.
이 시나리오는 공급망 공격의 기본 특성을 보여줍니다.
당신이 작성한 코드와 당신이 신뢰하는 코드. 당신이 설치하는 모든 의존성
npm install 다른 사람이 작성하고 다른 사람이 유지 관리하는 코드를 나타내며 잠재적으로
다른 사람들에 의해 타협되었습니다. 중간 규모의 Node.js 프로젝트에서 직접적인 종속성은 다음과 같습니다.
일반적으로 20-50개의 패킷이지만 전체 전이적 종속성 그래프는 도달할 수 있습니다.
쉽게 500-1000개의 라이브러리를 얻을 수 있습니다. 정말로 이 코드를 모두 확인하고 있나요?
OWASP Top 10:2025에 따르면 카테고리는 A03: 소프트웨어 및 데이터 무결성 오류 공급망 실패를 중요한 벡터로 명시적으로 포함합니다. 이건 둘 중 하나야 2025년 버전에 도입된 새로운 카테고리는 코드는 더 이상 종속성의 안전성을 무시할 수 없습니다. 이 기사에서는 다음을 제공합니다. 당신을 보호하는 구체적인 도구.
무엇을 배울 것인가
- 공급망 공격 분석: 타이포스쿼팅, 종속성 혼란, 잠금 파일 중독
- npm 감사, 실 감사, pnpm 감사: 고급 사용 및 자동화
- npm ci를 사용한 잠금 파일 무결성 및 해시 확인
- SBOM: CycloneDX 및 SPDX, NTIA 표준을 사용한 생성
- Snyk 및 dependencyabot: 지속적인 취약성 모니터링
- GitHub Actions 강화: SHA 고정 및 최소 권한
- 컨테이너 이미지 보안: Trivy, Syft 및 Cosign/Sigstore를 통한 서명
- 종속성 혼란과 비공개 npm 범위를 방어하는 방법
공급망 공격 분석
공급망 공격이 어떻게 작동하는지 이해하는 것이 자신을 방어하는 첫 번째 단계입니다. 몇 가지 주요 범주가 있으며 각각 고유한 특성과 공격 벡터를 가지고 있습니다.
오타스쿼팅(Typosquatting): 오타의 위험
Typosquatting은 일반적인 입력 오류를 이용합니다. 공격자가 게시
lodahs (대신 lodash), requst (대신
request), 또는 colerrs (대신 colors). 2025년에는
보안 연구원들은 다음을 위해 설계된 타이포스쿼트 패키지 세트를 식별했습니다.
스크립트를 통해 숨겨진 터미널을 실행하는 인기 라이브러리를 모방합니다. postinstall
자격 증명을 자동으로 추출합니다.
주요 방어책은 패키지를 설치하기 전에 이름을 철저히 확인하는 것입니다. Snyk 및 Socket.dev와 같은 도구는 이름의 유사성을 자동으로 분석합니다. 기존 패키지를 확인하고 설치 전에 잠재적인 타이포스쿼팅을 보고하세요.
종속성 혼란: 공개 범위와 비공개 범위
종속성 혼란(또는 네임스페이스 혼란)은 다음과 같이 문서화된 보다 정교한 공격입니다. 2021년 Alex Birsan이 처음으로 시도했습니다. 공격자는 npm에 패키지를 게시했습니다. 대상 회사의 비공개 내부 패키지와 이름이 같지만, 더 높은 버전. npm은 기본적으로 공개 레지스트리에서 최신 버전을 확인합니다. 악성 패키지를 유도하여 합법적인 패키지를 대체합니다.
실제 사례: 대규모 종속성 혼란
2021년 Alex Birsan은 Microsoft, Apple, PayPal을 포함한 35개 이상의 주요 회사를 손상시켰습니다. Shopify는 이 기술을 사용하여 버그 포상금으로 130,000달러 이상을 벌었습니다. 메커니즘은 간단했습니다. 구성 파일에서 내부 패키지 이름을 찾으세요. public(package.json, pyproject.toml)을 만들고 이를 버전 9.9.9로 공개 레지스트리에 게시합니다.
관리자 계정 탈취
2025년 가장 교활한 공격은 관리자를 표적으로 삼은 피싱이 얼마나 위험한지 보여주었습니다. 선호하는 통신사가 되었습니다. 합법적인 관리자의 계정이 손상되면, 공격자는 이미 신뢰할 수 있는 패키지의 악성 버전을 게시합니다. 지역사회는 신뢰한다 패키지가 보안 테스트를 통과하면 악성 코드가 프로덕션에 들어갑니다.
잠금 파일 중독
잠금 파일 중독 공격에서는 악의적인 기여자가 직접 잠금 파일을 수정합니다.
package-lock.json o yarn.lock 끌어오기 요청에서 다음을 가리킵니다.
예상과 다른 손상된 버전 또는 해시. 검토 과정에 포함되지 않은 경우
잠금 파일을 확인하면 악성 코드가 발견되지 않습니다.
npm 감사: 고급 사용법
npm audit 그러나 이를 올바르게 사용하려면 그 이상의 것이 필요합니다.
간단한 실행. 이를 개발 워크플로에 효과적으로 통합하는 방법을 살펴보겠습니다.
# 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'
종속성이 많은 프로젝트의 경우 취약점 수가 많을 수 있으며
관리하기 어렵다. 효과적인 전략은 파일을 구성하는 것입니다 .npmrc
프로젝트의 감사 정책과 함께 사용하거나 npm audit 파일이 있는
예외 구성.
# .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"
}
}
pnpm 감사 및 Yarn 감사
pnpm 또는 Yarn을 사용하는 경우 감사 명령은 유사하지만 몇 가지 중요한 차이점이 있습니다. pnpm은 종속성에 대해 보다 세부적인 제어를 제공하는 반면, Yarn v2/v3(Berry)는 해시 관리가 크게 향상되었습니다.
# 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'
잠금 파일 무결성: 1차 방어선
잠금 파일(package-lock.json, yarn.lock, pnpm-lock.yaml)
빌드 재현성과 보안에 중요합니다. 잠금 파일의 모든 항목
정확한 버전뿐만 아니라 패키지 콘텐츠의 해시도 포함됩니다.
npm ci와 npm install: 중요한 차이점
프로덕션 및 CI/CD에서는 항상 다음을 사용합니다. npm ci 대신에 npm install.
npm ci 잠금 파일에 지정된 버전을 정확하게 설치하고 확인하십시오.
각 패킷의 암호화 해시를 확인하고 잠금 파일이 동기화되지 않으면 실패합니다.
package.json. npm install 잠금 파일을 자동으로 업데이트할 수 있습니다.
# 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
보안을 위한 .npmrc 구성
파일 .npmrc 보안 정책으로 npm을 구성할 수 있습니다.
전체 프로젝트 또는 현재 사용자에게 적용됩니다.
# .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/
종속성 혼란: 비공개 범위로 자신을 방어하기
종속성 혼란에 대한 가장 효과적인 방어는 패키지를 비공개로 유지하는 것입니다. 항상 전용 범위를 사용하고 해당 npm은 해당 범위를 확인하도록 구성됩니다. 내부 레지스터에서만 독점적으로.
# 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: 소프트웨어 BOM
소프트웨어 자재 명세서(SBOM) 및 모든 구성 요소에 대한 완전한 공식 인벤토리 애플리케이션의 소프트웨어: 타사 라이브러리, 전이적 종속성, 버전, 라이선스 그리고 알려진 취약점. 이는 기업 보안을 위한 사실상의 요구 사항이 되었으며, 일부 부문(미국 정부, 중요 인프라)에서는 법으로 요구됩니다.
두 가지 주요 표준은 SPDX (소프트웨어 패키지 데이터 교환, Linux Foundation) 전자 사이클론DX (OWASP). SPDX는 라이센스 준수 지향적이며, CycloneDX는 보안 및 취약성 관리에 최적화되어 있습니다. 웹 애플리케이션의 경우, 일반적으로 CycloneDX가 최선의 선택입니다.
SBOM이 중요한 이유
종속성을 관리하기 위해 SBOM을 사용하는 프로젝트는 264일 단축을 달성합니다. SBOM이 없는 취약점에 비해 MTTR(Mean Time to Remediate)에 심각한 취약점이 발견되었습니다. Log4Shell과 같은 새로운 CVE의 경우 SBOM을 통해 몇 분 안에 식별이 가능합니다. 몇 주 동안 수동으로 분석하는 대신 영향을 받는 모든 프로젝트를 분석합니다.
CycloneDX를 사용한 SBOM 생성
# 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" } }]
# }
# ]
# }
Syft를 사용한 SBOM 생성
Syft by Anchore는 SBOM 생성을 위한 가장 완벽한 도구 중 하나입니다. 컨테이너 이미지, 파일 시스템 및 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 및 dependencyabot: 지속적인 모니터링
일회성 모니터링으로는 충분하지 않습니다. 새로운 취약점이 발견됩니다. 매일. Snyk 및 GitHub Didabot은 자동 경고를 통해 지속적인 모니터링을 제공합니다. 풀 요청을 업데이트합니다.
Snyk CLI 및 통합
# 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 Defendabot: 최적의 구성
# .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"
GitHub Actions 보안: SHA 고정 및 강화
GitHub Actions는 공급망에 대한 중요한 공격 벡터를 나타냅니다.
2024년에는 타협안이 tj-actions/changed-files 방법을 보여주었다
널리 사용되는 작업이 손상되어 다음에서 비밀을 추출하는 데 사용될 수 있습니다.
수천 개의 저장소. 주요 방어 및 SHA 고정: 참조 대신
태그당 하나의 작업(@v4), 커밋의 불변 해시가 사용됩니다.
# .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
안티 패턴: 타사 작업에 태그를 사용하지 마세요.
uses: some-org/some-action@v2 취약함: 관리자의 계정인 경우
손상되면 악성 코드를 가리키도록 태그가 업데이트될 수 있습니다.
항상 형식을 사용하십시오. uses: some-org/some-action@SHA_HASH # v2.0.0
가독성을 위해 태그를 주석으로 포함합니다. 다음과 같은 도구
pinact e action-pins 이 프로세스를 자동화합니다.
워크플로의 최소 권한
# 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
컨테이너 이미지 보안
애플리케이션이 Docker 컨테이너에 배포된 경우 공격 표면 기본 이미지와 설치된 OS 패키지도 포함됩니다. 트리비(Trivy)와 그리프(Grype)는 컨테이너 이미지의 취약점을 스캔하기 위한 주요 도구입니다.
# 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"
Angular 체크리스트: 공급망 보안
Angular 프로젝트의 경우 특정 도구 체인 고려 사항이 있습니다. (Angular CLI, webpack/esbuild, ng-packagr) 및 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();
# });
전체 워크플로: CI/CD의 보안 게이트
이러한 모든 도구를 일관된 보안 게이트에 통합하면 어떤 것도 보장되지 않습니다. 빌드는 공급망 보안 검사를 통과하지 않고 생산에 도달합니다.
# .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
}
타이포스쿼팅 감지 견적
새 패키지를 설치하기 전에 도구를 사용하여 테스트하는 것이 좋습니다. 전용 분석을 제공합니다. Socket.dev는 최고의 보안 분석 도구 중 하나입니다. 설치하기 전에 npm 패키지의
# 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
npm 패키지의 위험 신호
- 설치 후 스크립트: 설치 시 코드 실행
- 환경 변수에 대한 액세스:
process.env필요하지 않은 패키지에 - 알 수 없는 도메인에 대한 HTTP 요청: 어떤 UI 패키지도 설치 시 네트워크 호출을 해서는 안 됩니다.
- 기본 종속성(바인딩): 시스템 액세스로 C/C++ 코드 컴파일
- 1,000만 다운로드의 버전 0.0.1: 불가능, 통계조작 신호
- 유명한 패키지와 유사한 이름: 설치하기 전에 항상 npm.im을 확인하세요.
결론 및 다음 단계
공급망 보안은 일회성 활동이 아니라 지속적인 프로세스입니다. 2025년 가장 신뢰할 수 있는 패킷도 손상될 수 있다는 사실을 입증했습니다. 방어는 계층화되어야 합니다: 잠금 파일 확인, 자동 감사, SBOM 생성 각 릴리스마다 SHA 고정이 포함된 GitHub Actions, Snyk 또는 Didabot을 통한 지속적인 모니터링이 가능합니다.
가장 간단한 단계부터 시작하세요. 추가 npm audit --audit-level=high 당신에게
CI/CD, 항상 사용 npm ci 대신에 npm install 파이프라인에서,
저장소에서 dependencyabot을 활성화하세요. 이 세 가지 변경 사항이 대부분을 포괄합니다.
최소한의 시간 투자로 공격 벡터를 구축합니다.
다음 단계는 각 릴리스에서 SBOM을 생성하고 구현하는 것입니다. 이 기사에 표시된 것과 같은 완전한 보안 게이트. OWASP A03 공급 포함 이제 체인 고장은 공식적으로 2025년 상위 10위 안에 들었습니다. 더 이상 갖고 있으면 좋은 것이 아닙니다. 모든 개발자의 전문적인 책임입니다.
시리즈는 계속됩니다: 개발자를 위한 웹 보안
- 01 - 2025년 OWASP 상위 10대: 개발자 가이드
- 02 - XSS, CSRF 및 CSP: 프런트엔드 보안
- 03 - SQL 주입 및 입력 검증: 백엔드 보안
- 04 - 보안 인증: 세션 및 쿠키
- 05 - API 보안: OAuth 2.1, JWT 및 속도 제한
- 06 - 공급망 보안: npm 감사 및 SBOM (이 기사)
- 07 - 암호화 오류: 해싱, 암호화 및 토큰
- 08 - 개발자를 위한 DevSecOps: CI/CD의 SAST, DAST
시리즈에 대해서도 자세히 알아보세요. DevOps 프런트엔드(ID 250-255) 배포 워크플로에 보안을 통합합니다.







