
cve-2026-59891-control-lab v0.3.0
@sigstore/oci의 CVE-2026-59891을 위한 격리된 회귀 및 보안 통제 실험실
CVE-2026-59891 Regression & Control Lab
@sigstore/oci의 실제 취약 버전과 수정 버전을 같은 입력으로 비교하고,
환경별 노출 조건을 점검하는 격리형 실습 및 read-only 감사
프로젝트입니다.
이 프로젝트의 CVE Reporter는 gyubin02입니다.
채용·면접용 요약: CVE-2026-59891 취약점 관리 자동화 사례
무엇을 검증하나
CVE-2026-59891의 핵심은 Registry 인증정보를 고를 때 발생하는 hostname 혼동입니다.
0.7.0:cr.io가ghcr.io문자열 안에 있다는 이유로ghcr.io인증정보를 선택할 수 있습니다.0.7.1: hostname을 정규화한 뒤 정확히 일치하는 인증정보만 선택합니다.
이 저장소는 먼저 두 가지 credential 선택 시나리오를 자동 검증합니다.
- collision:
ghcr.io인증정보만 있는데 대상은cr.io - exact: 대상과 정확히 일치하는
cr.io인증정보가 있음
취약 버전은 첫 번째 시나리오에서 인증정보를 잘못 선택하고, 수정 버전은 거부해야 합니다. 두 버전 모두 두 번째 정상 시나리오는 성공해야 합니다.
여기에 실제 외부 Registry 대신 127.0.0.1의 일회성 mock
Registry를 사용한 동적 비교를 추가했습니다. 취약 버전 0.7.0은
로컬로 2건을 요청하고 인증 challenge 뒤 두 번째 요청에서 합성
Authorization header가 관찰됩니다. 수정 버전 0.7.1은 credential
선택 단계에서 거부되어 요청이 0건입니다. 결과에는 header 값 대신
관찰 여부와 요청 수만 남깁니다.
프로젝트 노출 점검 CLI
cve-2026-59891-audit는 대상 프로젝트의 package-lock.json과
명시적으로 지정한 Docker config의 metadata만 읽어 다음을
구분합니다.
- 영향받는
@sigstore/oci설치 위치와 버전 - 취약 버전 존재와 실제 노출 조건 충족 여부
- Registry 부분 문자열 충돌과 JSON key 순서상 실제 선택 대상
- 환경별 우선순위, 조치사항과 재시험 절차
- Registry hostname과 절대경로가 제거된 JSON·Markdown 증적
합성 fixture로 바로 실행:
npm run audit:demo
다른 Node.js 프로젝트 점검:
npm run audit:project -- \
--project ../target-project \
--docker-config ../review-copy/config.json \
--image cr.io/example/demo \
--destination-trust unknown \
--format markdown \
--output reports/cve-2026-59891.md
--destination-trust는 다음 중 하나를 반드시 명시합니다.
trusted: 코드와 allowlist로 destination이 제한됨을 확인untrusted: 외부입력이나 workflow 입력이 destination에 영향unknown: 아직 확인하지 못함
판정은 exposure_conditions_met, potential_exposure,
affected_component_only, not_detected, indeterminate로
나뉩니다. not_detected도 기록된 입력 범위에 대한 결과일 뿐
“안전”이나 “규정 준수”를 뜻하지 않습니다.
안전장치
- 회귀 랩은 실제
~/.docker/config.json을 읽거나 수정하지 않습니다. - 격리된 전용
HOME과 무가치한lab-user/LAB_ONLY_FAKE_TOKEN만 사용합니다. HOME, 랩 표식, 가짜 값이 모두 정확할 때만 패키지를 호출합니다.- 기존 선택 회귀 probe는 모든 HTTP(S), TCP, TLS, DNS와
fetch호출을 tripwire로 막습니다. - 동적 probe가 사용하는 Node 네트워크 표면에서는 OS가 배정한
정확한
127.0.0.1포트의 HTTP 요청만 허용합니다. 외부·다른 포트 HTTP, DNS resolver, TLS, UDP, 전역fetch·WebSocket은 차단합니다. - 자식 프로세스에 현재 세션의 토큰·Docker 환경변수를 상속하지 않습니다.
- stdout/stderr와 감사 결과에는 가짜 header조차 저장하지 않고, boolean과 요청 수만 남기는지 테스트합니다.
- 점검 CLI는
--docker-config를 생략할 수 없으며 HOME이나DOCKER_CONFIG에서 파일을 추론하지 않습니다. - CLI는 credential 값을 decode·hash·출력하지 않고, 대상 프로젝트 패키지·Docker·credential helper를 실행하거나 네트워크에 접속하지 않습니다.
- symlink, 중복 JSON key, 지원하지 않는 lockfile, 우선순위가 더 높은
npm-shrinkwrap.json이 발견되면 안전하다고 단정하지 않고 실패합니다.
취약 패키지를 의도적으로 설치하므로 npm package 배포는
"private": true로 막았습니다. 제품 코드의 의존성으로 사용하면
안 됩니다.
이 때문에 npm audit가 0.7.0을 보고하는 것은 예상된 결과이며,
예외의 범위와 이유는 SECURITY.md에 기록했습니다.
실행
요구 사항: Node.js 22.22.2+, 24.15.0+ 또는 26 이상. 권장 버전은
.nvmrc에 고정했습니다.
npm ci --ignore-scripts
npm test
npm run demo
npm run dynamic:demo
npm run audit:fixture
npm run audit:demo
npm run evidence
npm run demo의 핵심 예상 결과:
0.7.0 collision credential-selected
0.7.1 collision credential-rejected
0.7.0 exact credential-selected
0.7.1 exact credential-selected
Regression result: PASS
npm run dynamic:demo의 핵심 예상 결과:
{
"vulnerable": {
"packageVersion": "0.7.0",
"credentialSelection": "credential-selected",
"requestCount": 2,
"authorizationObserved": true,
"digestVerified": true,
"networkPolicy": "exact-loopback-only"
},
"fixed": {
"packageVersion": "0.7.1",
"credentialSelection": "credential-rejected",
"requestCount": 0,
"authorizationObserved": false,
"digestVerified": false,
"networkPolicy": "exact-loopback-only"
},
"regressionResult": "PASS"
}
전체 자동화 테스트는 34개입니다. npm run evidence는 검사 대상
산출물 6개와 그 무결성을 검증하는 SHA256SUMS를 합쳐 총 7개
파일을 생성합니다.
이 프로젝트가 보여주는 역량
- 실제 CVE의 발생 조건을 코드 수준에서 설명하고 안전하게 재현
- 취약 버전과 수정 버전을 동일 조건에서 비교하는 회귀 테스트 설계
- 합성 credential의 로컬 전송 여부까지 동적으로 비교하는 loopback-only 시험 설계
- 공개 CVSS와 별도로 실제 환경의 공격 전제조건을 평가
- package-lock v1·v2·v3, alias와 중첩 dependency를 정적으로 식별
- 비밀정보를 배제한 JSON·Markdown 감사 증적 자동 생성
- 발견 → 영향 분석 → 수정 검증 → 통제로 이어지는 취약점 관리
- 실제 인증정보를 건드리지 않는 실패 안전형 보안 테스트
출처와 범위
이 프로젝트는 제한된 교육용 통제 평가입니다. loopback 결과는 합성 환경의 동작 차이만 입증하며, 실제 기업 환경의 credential 노출·침해나 통제 효과를 입증하지 않습니다. CISA 자격, ISMS-P 인증 또는 특정 조직의 규정 준수를 뜻하지 않습니다. Node API guard는 잠근 dependency의 관찰된 실행경로를 위한 방어층이지, OS 수준 network namespace나 방화벽은 아닙니다.
상세한 범위, 테스트, 위험 및 통제 문서는 docs/에 있으며,
npm run evidence는 재현 가능한 실행 증적과 SHA-256 manifest를
생성합니다.