Devin.KR

의존성 공지의 적용 조건

65분 안팎

학습 목표

설치 버전과 사용 경로로 영향 여부를 판단합니다.

개념

왜 공지 제목만 보고 결론을 내리면 안 되나요

보안 공지가 왔다고 모든 앱이 같은 영향을 받는 것은 아닙니다. 패키지 이름과 버전이 맞아도 특정 기능을 호출해야 문제가 발생할 수 있고, 직접 설치하지 않은 하위 패키지가 사용 경로에 있을 수도 있습니다. 반대로 우리 소스에서 import가 안 보인다는 이유로 상위 패키지의 내부 호출을 제외하면 영향을 놓칩니다. 이번 목표는 설치 자료·공지 조건·앱 경로를 분리해서 판단 근거와 다음 검증 계획을 남기는 것입니다.

미션의 TRAINING-2026-07은 실제 CVE나 실제 패키지 공지가 아닙니다. package-lock.fixture.json은 분석 연습용 스냅샷이며 npm이 설치하는 package-lock.json이 아닙니다. vault-preview와 view-codec도 교재에서 만든 가상 이름입니다. 실제 앱은 Node.js 표준 모듈과 Python sqlite3로 실행합니다. 가상 설치 그래프를 읽는 판단과 현재 코드의 실행 관찰을 같은 증거라고 쓰지 않습니다.

무엇을 어떤 순서로 확인하나요

advisory.json의 패키지명은 view-codec이고 영향 버전은 2.0.0과 2.0.1입니다. 문제 조건은 외부 입력을 decodePreview 경로로 처리하는 경우이며 수정 후보는 2.0.2입니다. 가상 잠금 자료에는 vault-preview 1.4.2 아래 view-codec 2.0.1이 있습니다. 직접 의존성 목록에 view-codec가 없어도 하위 경로에 있으므로 버전 일치는 확인합니다. 1.4.2와 2.0.1은 서로 다른 패키지의 버전입니다.

버전 비교는 이 fixture에 열거된 값의 포함 여부로만 합니다. 문자열 사전순 비교로 일반적인 버전 범위를 판정하지 않습니다. 예를 들어 2.0.10과 2.0.2의 순서는 문자열 정렬과 의미 있는 버전 비교가 다를 수 있습니다. 실제 공지는 사전 릴리스·배포판 패치·운영체제 조건을 포함할 수 있어 공급자의 범위 표기와 설치 도구의 해석을 확인해야 합니다. 여기서는 복잡한 범위 계산을 구현했다고 주장하지 않습니다.

사용 경로를 코드 근거로 설명합니다

현재 서버 경로는 server.cjs → secure-app.cjs → security.cjs의 renderDocument입니다. 이 함수는 제목과 내용을 고정 HTML 텍스트 위치에 넣기 전에 escapeText로 처리합니다. decodePreview 호출이나 가상 패키지 import는 현재 코드에 없습니다. 따라서 이번 제공 코드에서 공지의 기능 조건은 확인되지 않습니다. 버전은 영향 범위지만 제공된 경로는 미사용이라는 두 문장을 함께 써야 설치 사실을 지우지 않습니다.

사용 경로가 없다는 판단은 점검한 코드와 실행 구성 범위에 한정합니다. 운영 플러그인·선택 기능·별도 빌드에 같은 패키지가 있다면 추가 조사가 필요합니다. 검색 결과가 없다는 것만으로 동적 로딩이 없는지 증명할 수는 없습니다. 미션의 evidence에는 현재 표시 경로와 decodePreview 부재의 근거를 따로 적습니다. 앞으로 미리보기 기능을 추가할 때 이 판단을 재검토하는 조건도 기록합니다.

설계 판단을 제출물로 만듭니다

dependency-review.json에는 notice, installed, dependencyPath, reachable, evidence, decision, candidate, plan, testEvidence, remainingRisk를 씁니다. reachable은 이번 코드에서 공지 조건의 경로를 확인했는지 나타내는 불리언입니다. false를 안전 인증처럼 사용하지 않습니다. decision에는 버전 일치와 기능 미사용의 범위를 함께 기록하며, remainingRisk에는 실제 설치 자료나 취약점 데이터베이스 조회를 하지 않았음을 적습니다.

evidence 두 항목은 문장 길이를 늘리기 위한 칸이 아닙니다. 하나는 실제 자료 표시 함수로 이어지는 호출 연결, 다른 하나는 공지의 기능 조건과 현재 코드의 차이를 보여 줍니다. 잠금 fixture 경로는 vault-preview@1.4.2 → view-codec@2.0.1입니다. 담당자가 같은 파일을 열어 판단을 다시 확인할 수 있어야 합니다. 보고서 E07은 이 판단 자료를 참조하며 설치 버전·조건·후속 행동을 연결합니다.

교체 후보와 검증 계획

수정 버전 번호가 있다고 하위 패키지를 강제로 바꾸면 상위 패키지의 호환성 요구를 깨뜨릴 수 있습니다. 후보 2.0.2에 대해 상위 패키지가 허용하는 버전과 변경 사항을 검토하고, 격리 환경에서 잠금 자료 변경을 비교하는 계획을 세웁니다. 실제 작업이라면 재현 가능한 설치 절차와 아티팩트 출처도 확인합니다. 이번 모듈에서는 네트워크 설치를 하지 않고 가상 교체 계획만 작성합니다.

회귀 기준은 단순히 기동 성공 하나가 아닙니다. 작은따옴표 제목의 검색, 원문 저장 보존, HTML 텍스트 변환, 타인 자료 거절, CSRF 누락 거절, 정상 소유자의 생성·조회·수정이 포함됩니다. query-test.cjs, output-test.cjs, input-test.cjs는 이 앱의 기존 동작 근거입니다. 이 테스트가 지금 통과하는 것과 가상 패키지를 실제 교체한 뒤 통과하는 것은 다른 주장입니다. 후자는 이번 과제에서 관찰하지 않았습니다.

자동 검사와 사람의 검토 경계

verify-dependencies.py는 공지와 설치 버전의 연결, 하위 의존성 경로, 근거 필드, 후보 및 테스트 파일의 존재를 검사합니다. 문서 완전성 확인이며 취약점 탐지기가 아닙니다. 실제 경로의 도달 가능성이나 호환성 판단을 인증하지 않습니다. AssertionError가 나면 직전 비교식과 JSON의 필드를 대조합니다. 기대값에 맞추려고 문장을 꾸미기보다 fixture를 다시 읽고 근거를 고치는 것이 과제의 목적입니다.

검사가 PASS여도 검토자는 decision과 remainingRisk를 읽어야 합니다. 지금 적용 가능한 통제와 미래 조건을 구분했는지, 설치 성공을 꾸며 쓰지 않았는지, 교체 실패 때 유출 키로 되돌리는 계획이 없는지 살펴봅니다. 상위 패키지의 영향이 불확실하면 확인할 코드·담당자·검증 조건을 구체적으로 남깁니다. 모르는 상태를 영향 없음으로 바꾸는 것은 판단을 빠르게 만드는 대신 위험을 숨깁니다.

누적 미션을 마무리합니다

security-secrets-dependencies-mission의 check.sh는 설정·교체·로그 검사 다음에 m06의 저장·입력·출력·인가 회귀와 E06 참조 검사를 실행하고 마지막에 가상 의존성 자료를 검사합니다. 처음 config-test에서 중단되면 뒤 검사는 아직 실행되지 않은 것입니다. TODO를 해결할 때마다 전체 명령을 다시 실행하고 E07에 자신의 종료 코드와 PASS 행을 기록합니다. 마지막 한 행만으로 실행되지 않은 외부 검사를 성공으로 쓰지 않습니다.

이전 Docker 정책은 legacy-check.sh에 남아 있으며 샌드박스에서는 external PENDING입니다. 로컬 성공은 컨테이너 계정·파일 권한이나 실제 브라우저 쿠키 정책의 검증을 대신하지 않습니다. 더 읽기의 운영 보안 장은 의존성 도구와 실행 권한을 더 넓게 연결합니다. 여기서 완성하는 결과는 근거가 있는 영향 판단, 안전한 교체 계획, 비밀 노출 방지와 기존 기능 회귀를 묶은 작은 변경 보고서입니다.

관련 원칙과 도구의 범위는 npm audit 문서에서 확인할 수 있습니다. 이 레슨의 판정은 제공된 교재 코드와 고정 fixture 범위에 한정합니다.

따라하기

가상 하위 버전과 영향 목록을 대조합니다

공지의 두 버전만 열거한 독립 예제입니다. 실제 패키지 조회나 설치를 하지 않습니다.

import json
lock={'packages':{'node_modules/vault-preview/node_modules/view-codec':{'version':'2.0.1'}}}
v=lock['packages']['node_modules/vault-preview/node_modules/view-codec']['version']
print(v)
print(v in ['2.0.0','2.0.1'])

실행 결과

2.0.1
True

버전 일치와 경로 조건을 따로 기록합니다

현재 앱에서 사용하는 표시 함수와 공지 조건의 함수는 다릅니다.

const installed='2.0.1',affected=['2.0.0','2.0.1'];const actualPath=['server.cjs','secure-app.cjs','renderDocument'];console.log(affected.includes(installed));console.log(actualPath.includes('decodePreview'));

실행 결과

true
false

판단 자료의 근거를 작성합니다

미션 ZIP의 advisory.json과 package-lock.fixture.json을 읽습니다. dependency-review.json에 설치 버전·하위 경로·현재 표시 경로·공지 기능 부재·후보·검증 계획·잔여 불확실성을 적습니다. python3 verify-dependencies.py는 구조 검사이며 영향 판단은 사람이 검토합니다.

누적 미션을 검증하고 E07을 보완합니다

설정·교체·로그 TODO를 완성한 뒤 bash check.sh를 실행합니다. 자신의 PASS 행과 종료 코드를 E07에 적습니다. 기존 Docker 검사의 bash legacy-check.sh는 external PENDING이며 실제 실행 전 성공으로 쓰지 않습니다.

확인 문제

실습

누적 미션의 advisory.json·package-lock.fixture.json과 현재 표시 함수 경로를 읽고 dependency-review.json을 작성합니다. notice·installed·dependencyPath·reachable·evidence 두 항목 이상·decision·candidate·plan 두 항목 이상·testEvidence·remainingRisk를 포함합니다. 버전 일치와 기능 미사용을 함께 적고 실제 설치를 관찰했다고 쓰지 않습니다. 후보 교체 전 상위 호환성·잠금 변화·입력/출력/인가/CSRF 회귀 및 재검토 조건을 제시합니다. verify-dependencies.py는 자료 연결 검사이고 최종 판단은 사람이 검토합니다.

더 읽기

면접 질문

  • 비밀값을 코드와 로그에서 보호하는 방법을 설명합니다.