왜 나는 npm audit를 믿지 않게 되었는가 (그리고 직접 만들었다)

발행: (2026년 5월 5일 AM 02:42 GMT+9)
5 분 소요
원문: Dev.to

Source: Dev.to

package-lock.json에서 CycloneDX SBOM 및 결정론적, audit‑ready 위험 보고서 생성

npm audit을 실행합니다. “47개의 취약점”이라고 표시됩니다.
멋지죠. 실제로 중요한 것은 어느 것인가요? 프로덕션 번들에 있는 것? 당신은 모릅니다.

그래서 선택은:

  • 모든 것을 무시 → 그대로 배포
  • 어쨌든 신호를 잃음

실제 문제는 취약점이 아니라 결정‑내리기입니다.

실제 문제는 취약점이 아니라 결정‑내리기

대부분의 도구는 다음과 같이 답합니다:

“무엇이 잘못됐나요?”

하지만 다음은 답하지 않습니다:

“이것에 대해 무엇을 해야 하나요?”

마지막 질문이 진짜 문제입니다.

등장: audit‑ready

점수가 아니라 결정을 제공합니다. 결정론적이며, 재현 가능하고, 감사 가능하게 설계되었습니다.

🔑 reasonCode가 CVSS를 대체합니다

각 의존성은 정확히 하나의 라벨을 갖습니다. 예:

DEV_DEPENDENCY_ONLY

해석이 필요 없습니다. CI 설정이 간단해집니다 – “고위험 취약점 7개”가 아니라.

🧠 모든 것을 형성하는 제약 조건

동일한 package-lock.json → 동일한 출력. 언제나.

어떻게 강제되는가

핵심 로직에는 강제 제약이 있습니다:

const banned = ['Date', 'Date.now()', 'Math.random()', 'process.env'];

결정론이 깨지면 → 빌드 실패.

⚙️ 엔진은 의도적으로 단순합니다

점수도, 휴리스틱도 없습니다.
첫 번째 매치가 승리 – 우선순위는 규칙 순서에 따라 정의됩니다.

🧾 실제로 사용할 수 있는 출력

모든 것이 reasonCode에 연결됩니다.

🔐 보안: 이 도구는 스스로를 감사합니다

감사 아티팩트를 생성한다면, 도구 자체가 신뢰할 수 있어야 합니다.

환경 접근 금지

핵심 엔진은 다음을 읽을 수 없습니다:

  • 환경 변수

출력은 입력 + 도구 버전만 의존

결정론적 PURL 생성

표준 인코더(encodeURIComponent, URL)는 Node 버전에 따라 다를 수 있으므로 PURL은 직접 생성합니다.

  • 동일한 패키지 → 동일한 PURL → 언제나

스키마 검증 (입력 + 출력)

검증에 실패하면 → 아무 것도 기록되지 않습니다.

불변 출력

조용한 변형이 없습니다. 예외는 영구히 존재할 수 없으며, 모든 예외는 이유가 필요합니다. 만료된 경우? audit-ready audit-exceptions → exit 1. 조용히 무시하는 경우는 없습니다.

설계상 네트워크 안전

외부 호출은 하나뿐:

  • PURL을 사용한 OSV API

실패하더라도 SBOM은 계속 생성됩니다. 도구는 자체 파이프라인을 스스로에 적용합니다 – 같은 코드, 같은 규칙. 거짓말을 하면 스스로를 드러냅니다.

⚠️ 이 도구가 하지 않는 일

다루지 않는 경우 → 크게 실패합니다.

왜 중요한가

더 나은 스캔이 목적이 아닙니다. 재현 가능한 결정이 목적입니다. 프로덕션 릴리스는 Phase 3 이후에 계획됩니다.

💬 피드백을 기다립니다

https://github.com/neve7er/audit-ready

최종 생각

대부분의 도구는 똑똑해지려 합니다. 이 도구는 예측 가능해지려 합니다. 보안에서는 예측 가능성이 지능보다 뛰어납니다.

0 조회
Back to Blog

관련 글

더 보기 »