같은 프로젝트에서 npm audit와 DepGra를 실행했는데, 각각 잡아낸 내용은 이렇다

발행: (2026년 3월 15일 오후 10:26 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

번역할 텍스트를 제공해 주시면 한국어로 번역해 드리겠습니다.

npm audit

npm audit은 8개의 패키지에서 10개의 취약점(중간 3개, 높음 7개)을 보고했습니다:

패키지버전권고사항심각도
serialize‑javascript6.0.2RegExp.flags를 이용한 원격 코드 실행 (RCE)높음
next15.5.92개의 권고사항높음
minimatch3.1.2, 9.0.5각각 3개의 ReDoS 권고사항높음
flatted3.3.3무제한 재귀 DoS높음
rollup4.54.0경로 탐색을 통한 임의 파일 쓰기높음
ai4.3.19파일 유형 화이트리스트 우회보통
jsondiffpatch0.6.0HtmlFormatter를 통한 XSS보통
ajv6.12.6, 8.17.1$data 옵션을 이용한 ReDoS보통

npm audit은 또한 수정이 가능한지와 해당 수정이 깨뜨리는 변경(breaking changes)을 요구하는지 여부를 표시합니다—이는 DepGra가 제공하지 않는 정보입니다.

DepGra scan

DepGra는 동일한 package-lock.json6.5 초 만에 스캔했으며, 10개의 패키지에서 12개의 고유 advisory를 발견했습니다:

SeverityGHSA IDAffected package(s)
CRITICALGHSA-5c6j-r48x-rmvqserialize-javascript@6.0.2
HIGHGHSA-23c5-xmqv-rm74minimatch@3.1.2, minimatch@9.0.5
HIGHGHSA-25h7-pfq9-p65fflatted@3.3.3
HIGHGHSA-3ppc-4f35-3m26minimatch@3.1.2, minimatch@9.0.5
HIGHGHSA-7r86-cg39-jmmjminimatch@3.1.2, minimatch@9.0.5
HIGHGHSA-h25m-26qc-wcjfnext@15.5.9
HIGHGHSA-mw96-cpmx-2vgcrollup@4.54.0
MEDIUMGHSA-33vc-wfww-vjfvjsondiffpatch@0.6.0
MEDIUMGHSA-5f7q-jpqc-wp7hnext@15.5.9
MEDIUMGHSA-9g9p-9gw9-jx7fnext@15.5.9
MEDIUMGHSA-rwvc-j5jr-mgvhai@4.3.19
UNKNOWNGHSA-2g4f-4pwh-qvx6ajv@6.12.6, ajv@8.17.1

npm audit에서 보고된 11개의 advisory가 모두 DepGra 결과에 포함되어 있으며, 추가 advisory 1개가 더 있습니다:

  • GHSA-5f7q-jpqc-wp7h (CVE‑2025‑59472)Next.js의 PPR resume 엔드포인트를 통한 무제한 메모리 사용 (2026‑01‑28 발표). 이 advisory는 OSV.dev(DepGra의 데이터 소스)에는 존재하지만 npm audit이 사용하는 GitHub Advisory Database에는 아직 포함되지 않았습니다.

차이가 발생한 이유

  • 데이터 소스: DepGra는 여러 취약점 피드를 통합하는 OSV.dev를 조회합니다. npm auditGitHub Advisory Database를 조회합니다. 두 소스 간의 업데이트 시점 차이로 인해 결과가 달라질 수 있습니다.
  • 심각도 점수: npm auditserialize-javascripthigh로 분류하지만, DepGra는 전체 CVSS 벡터를 가져와 critical으로 평가합니다.
  • 카운팅 방법: npm audit은 취약한 패키지 인스턴스마다 하나씩 카운트하고, DepGra는 고유 CVE ID 기준으로 카운트합니다.

그래프 인사이트

DepGra 스캔을 그래프 뷰로 로드하면 두 가지 패턴이 눈에 띕니다:

  1. Minimatch가 병목 현상
    평면 목록에는 minimatch에 대한 고위험 권고가 세 개 표시됩니다. 그래프를 보면 minimatch@3.1.2가 여러 널리 사용되는 패키지(@sentry/node, @typescript-eslint/typescript-estree, glob)의 전이 의존성임을 알 수 있습니다. 따라서 그 폭발 반경은 심각도만으로 판단할 수 있는 것보다 훨씬 큽니다.

  2. serialize-javascript에 대한 다중 위험 경로
    평면 목록에는 단일 항목만 표시되지만, 그래프에서는 두 개의 별도 의존성 체인이 나타납니다:

    • copy-webpack-plugin → serialize-javascript@6.0.2
    • terser-webpack-plugin → serialize-javascript@6.0.2

    두 경로 모두 심각한 RCE 취약점으로 이어지며, 수동 npm ls 분석에 의존하기보다 토폴로지를 시각화하는 것이 얼마나 유용한지를 강조합니다.

기술 스택

  • Parsers: package-lock.json, Cargo.lock, poetry.lock, requirements.txt, go.mod
  • Vulnerability source: OSV.dev 배치 API (모든 패키지에 대해 단일 요청을 보낸 뒤 상세 정보를 추가로 가져옴)
  • Storage & analysis: SQLite + NetworkX (중심성 점수 계산, 경로 탐색)
  • API: Flask (REST)
  • Frontend: Svelte + Cytoscape.js (그래프 렌더링)
  • Layout algorithm: DAG 레이아웃을 위한 위상 정렬 – O(V + E), 1,300개 이상의 노드를 효율적으로 처리
  • Python requirements.txt handling: lock 파일이 없으므로 PyPI API를 통해 전이적 의존성을 해결함

설치 및 사용

# Clone the repository
git clone https://github.com/KPCOFGS/depgra
cd depgra

# Backend setup
cd backend
uv venv .venv
source .venv/bin/activate
uv pip install -r requirements.txt
cd ..

# Frontend setup
cd frontend
npm install
npm run build
cd ..

# Run the server
python run.py
# Open http://127.0.0.1:5000

CLI 대안

# Scan a lockfile
python run.py scan path/to/package-lock.json

# Scan a requirements file and fail on HIGH severity or above
python run.py scan requirements.txt --fail-on HIGH

Limitations

  • 자동 복구 없음: DepGra는 버전 업그레이드를 제안하거나 고정 풀 리퀘스트를 생성하지 않습니다(npm audit fix와 달리).
  • 범위: 의존성 취약점 시각화에만 초점을 맞추며, 컨테이너 스캔, 라이선스 준수, 비밀 탐지는 지원하지 않습니다.
  • 심각도 차이: 분류는 OSV.dev에서 제공되며, 다른 도구(예: Snyk, npm audit)에서 보고되는 결과와 다를 수 있습니다.
  • 대형 그래프: 1,000개 이상의 패키지에 대한 시각화는 복잡해지며, 여전히 작동하지만 작은 그래프에 비해 깔끔하지 않을 수 있습니다.

향후 방향

  • SBOM 내보내기 (CycloneDX / SPDX)
  • 자동화된 수정 제안 (CVE를 해결하는 최소 버전 업그레이드)
  • CI/CD 통합을 위한 GitHub Action

이 프로젝트는 MIT‑라이선스를 따르며 피드백을 환영합니다.

0 조회
Back to Blog

관련 글

더 보기 »

JavaScript 소개

소개 오늘 수업에서 짧게 JavaScript에 대해 배웠으므로, 이 블로그에서 JavaScript에 관한 몇 가지 사실을 공유하려 합니다. JavaScript란? JavaScript…