같은 프로젝트에서 npm audit와 DepGra를 실행했는데, 각각 잡아낸 내용은 이렇다
Source: Dev.to
번역할 텍스트를 제공해 주시면 한국어로 번역해 드리겠습니다.
npm audit
npm audit은 8개의 패키지에서 10개의 취약점(중간 3개, 높음 7개)을 보고했습니다:
| 패키지 | 버전 | 권고사항 | 심각도 |
|---|---|---|---|
| serialize‑javascript | 6.0.2 | RegExp.flags를 이용한 원격 코드 실행 (RCE) | 높음 |
| next | 15.5.9 | 2개의 권고사항 | 높음 |
| minimatch | 3.1.2, 9.0.5 | 각각 3개의 ReDoS 권고사항 | 높음 |
| flatted | 3.3.3 | 무제한 재귀 DoS | 높음 |
| rollup | 4.54.0 | 경로 탐색을 통한 임의 파일 쓰기 | 높음 |
| ai | 4.3.19 | 파일 유형 화이트리스트 우회 | 보통 |
| jsondiffpatch | 0.6.0 | HtmlFormatter를 통한 XSS | 보통 |
| ajv | 6.12.6, 8.17.1 | $data 옵션을 이용한 ReDoS | 보통 |
npm audit은 또한 수정이 가능한지와 해당 수정이 깨뜨리는 변경(breaking changes)을 요구하는지 여부를 표시합니다—이는 DepGra가 제공하지 않는 정보입니다.
DepGra scan
DepGra는 동일한 package-lock.json을 6.5 초 만에 스캔했으며, 10개의 패키지에서 12개의 고유 advisory를 발견했습니다:
| Severity | GHSA ID | Affected package(s) |
|---|---|---|
| CRITICAL | GHSA-5c6j-r48x-rmvq | serialize-javascript@6.0.2 |
| HIGH | GHSA-23c5-xmqv-rm74 | minimatch@3.1.2, minimatch@9.0.5 |
| HIGH | GHSA-25h7-pfq9-p65f | flatted@3.3.3 |
| HIGH | GHSA-3ppc-4f35-3m26 | minimatch@3.1.2, minimatch@9.0.5 |
| HIGH | GHSA-7r86-cg39-jmmj | minimatch@3.1.2, minimatch@9.0.5 |
| HIGH | GHSA-h25m-26qc-wcjf | next@15.5.9 |
| HIGH | GHSA-mw96-cpmx-2vgc | rollup@4.54.0 |
| MEDIUM | GHSA-33vc-wfww-vjfv | jsondiffpatch@0.6.0 |
| MEDIUM | GHSA-5f7q-jpqc-wp7h | next@15.5.9 |
| MEDIUM | GHSA-9g9p-9gw9-jx7f | next@15.5.9 |
| MEDIUM | GHSA-rwvc-j5jr-mgvh | ai@4.3.19 |
| UNKNOWN | GHSA-2g4f-4pwh-qvx6 | ajv@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 audit은 GitHub Advisory Database를 조회합니다. 두 소스 간의 업데이트 시점 차이로 인해 결과가 달라질 수 있습니다. - 심각도 점수:
npm audit은serialize-javascript를 high로 분류하지만, DepGra는 전체 CVSS 벡터를 가져와 critical으로 평가합니다. - 카운팅 방법:
npm audit은 취약한 패키지 인스턴스마다 하나씩 카운트하고, DepGra는 고유 CVE ID 기준으로 카운트합니다.
그래프 인사이트
DepGra 스캔을 그래프 뷰로 로드하면 두 가지 패턴이 눈에 띕니다:
Minimatch가 병목 현상
평면 목록에는minimatch에 대한 고위험 권고가 세 개 표시됩니다. 그래프를 보면minimatch@3.1.2가 여러 널리 사용되는 패키지(@sentry/node,@typescript-eslint/typescript-estree,glob)의 전이 의존성임을 알 수 있습니다. 따라서 그 폭발 반경은 심각도만으로 판단할 수 있는 것보다 훨씬 큽니다.serialize-javascript에 대한 다중 위험 경로
평면 목록에는 단일 항목만 표시되지만, 그래프에서는 두 개의 별도 의존성 체인이 나타납니다:copy-webpack-plugin → serialize-javascript@6.0.2terser-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.txthandling: 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:5000CLI 대안
# 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 HIGHLimitations
- 자동 복구 없음: DepGra는 버전 업그레이드를 제안하거나 고정 풀 리퀘스트를 생성하지 않습니다(
npm audit fix와 달리). - 범위: 의존성 취약점 시각화에만 초점을 맞추며, 컨테이너 스캔, 라이선스 준수, 비밀 탐지는 지원하지 않습니다.
- 심각도 차이: 분류는 OSV.dev에서 제공되며, 다른 도구(예: Snyk, npm audit)에서 보고되는 결과와 다를 수 있습니다.
- 대형 그래프: 1,000개 이상의 패키지에 대한 시각화는 복잡해지며, 여전히 작동하지만 작은 그래프에 비해 깔끔하지 않을 수 있습니다.
향후 방향
- SBOM 내보내기 (CycloneDX / SPDX)
- 자동화된 수정 제안 (CVE를 해결하는 최소 버전 업그레이드)
- CI/CD 통합을 위한 GitHub Action
이 프로젝트는 MIT‑라이선스를 따르며 피드백을 환영합니다.