LabHub
배우기 러닝패스 코스

ビルドは緑だったのに、あのライブラリを入れたのは誰か

境界を合わせ、今日直せるものだけ残す

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

SBOM 을 취약점 자료와 대조해 실제로 영향받는 것만 골라 내고, '고칠 판이 있는가' 와 '사용자에게 닿는가' 라는 두 축으로 갈라 정책 관문을 프로그램으로 적습니다.

왜 중요한가

스캐너를 처음 돌리면 빨간 줄이 수백 개 나옵니다. 그 목록을 그대로 개발팀에 보내면 아무 일도 일어나지 않습니다 — 다 고칠 수 없다는 것을 모두가 알기 때문입니다. 줄어드는 자리는 두 곳입니다. 첫째, 구간 판정이 정확해야 합니다. 고쳐진 버전을 쓰고 있는데도 걸리는 오탐이 섞이면 목록 전체의 신뢰가 무너집니다. 둘째, 고칠 판이 있는 것과 없는 것은 다른 일입니다. 고칠 판이 있으면 오늘 올리면 되고, 없으면 완화책과 기한을 적어 면제로 관리해야 합니다. 이 둘을 섞어 두면 회의는 "심각도가 높다 / 낮다" 로만 돌고 아무것도 바뀌지 않습니다.

단계

  1. /opt/fixtures/sbom/feeds/advisories.json 를 읽어 /root/adv/01-feed.json 에 자료의 모양을 적습니다.
  2. /opt/fixtures/sbom/sbom/paygate-1.4.2.cdx.json 의 components 를 평평하게 펴 /root/adv/02-components.json 에 씁니다.
  3. /root/adv/semver_cmp.py 에 버전 비교기를 만듭니다.
  4. 경계값까지 맞춰 영향받는 것만 /root/adv/04-findings.json 에 씁니다.
  5. 고칠 판이 있는 것만 /root/adv/05-upgrade-plan.json 으로 옮깁니다.
  6. 사용자에게 닿는 것과 빌드에서 끝나는 것을 /root/adv/06-shipped.json 에 가릅니다.
  7. /root/adv/gate-vuln.py 로 정책을 적고 결과를 /root/adv/07-verdict.json 에 남깁니다.
  8. /root/adv/waivers.json 의 면제를 적용해 /root/adv/08-verdict.json 으로 다시 판정합니다.

참고

자료가 무엇을 말하는지부터 읽는다

/opt/fixtures/sbom/feeds/advisories.json 를 읽어 /root/adv/01-feed.json 에 advisories·with_fixed·without_fixed·packages 를 저장하세요. with_fixed 는 ranges 의 events 에 fixed 가 하나라도 있는 권고의 수, without_fixed 는 나머지, packages 는 affected 의 패키지 이름을 사전순으로 담은 배열입니다.

OSV 의 events 는 '도입됐다 / 고쳐졌다 / 여기까지 영향받는다' 를 시간순으로 적은 타임라인입니다. fixed 가 없는 권고가 있다는 것 자체가 이 실습의 주제입니다.

무엇을 대조할 것인지 목록으로 세운다

/opt/fixtures/sbom/sbom/paygate-1.4.2.cdx.json 의 components 에서 name·version·scope 만 남겨 /root/adv/02-components.json 에 이름 사전순 배열로 저장하세요. scope 는 SBOM 에 적힌 값을 그대로 옮깁니다.

대조의 왼쪽이 이 목록이고 오른쪽이 취약점 자료입니다. 왼쪽을 먼저 평평하게 펴 두면 뒤 단계가 전부 쉬워집니다.

버전을 문자열로 비교하면 안 되는 이유를 코드로 못박는다

/root/adv/semver_cmp.py 에 compare(a, b) 함수를 만드세요. 두 인자는 X.Y.Z 꼴의 문자열이고, a 가 작으면 -1, 같으면 0, 크면 1 을 그대로 돌려줍니다. 세 자리를 각각 정수로 비교해야 합니다.

문자열로 비교하면 "1.9.0" 이 "1.10.0" 보다 크다고 나옵니다. 채점기는 그런 쌍을 포함해 여러 경우를 직접 넣어 봅니다.

경계값까지 정확히 맞춘다

/root/adv/semver_cmp.py 의 비교로 /opt/fixtures/sbom/sbom/paygate-1.4.2.cdx.json 과 /opt/fixtures/sbom/feeds/advisories.json 를 대조해 실제로 영향받는 것만 /root/adv/04-findings.json 에 id 사전순 배열로 저장하세요. 각 항목은 id·package·version·severity·scope·fix_available·fixed_in 입니다. severity 는 severity[0].score 를, scope 는 SBOM 의 값을 옮깁니다. fixed_in 은 그 버전이 속한 구간을 닫는 fixed 값이고 없으면 null, fix_available 은 그 불리언입니다. introduced 의 "0" 은 어떤 버전보다도 앞을 뜻하는 특수값입니다.

구간은 introduced 이상 fixed 미만입니다 — fixed 와 같은 버전은 이미 고쳐진 것입니다. last_affected 는 그날까지 확인된 천장이라 그 값 자체는 아직 영향받습니다. 한 권고에 구간이 둘 이상일 수도 있습니다.

오늘 고칠 수 있는 것만 계획으로 옮긴다

/root/adv/04-findings.json 에서 fix_available 이 true 인 것만 골라 /root/adv/05-upgrade-plan.json 에 package 사전순 배열로 저장하세요. 각 항목은 package·from·to·advisory 이고, to 는 fixed_in, advisory 는 권고 id 입니다.

'고칠 판이 있는가' 는 심각도와 다른 축입니다. 오늘 올릴 수 있는 것과 오늘은 못 올리는 것을 먼저 갈라야 회의가 끝납니다.

사용자에게 닿는 것과 빌드에서 끝나는 것을 가른다

/root/adv/06-shipped.json 에 shipped 와 dev_only 를 저장하세요. 둘 다 권고 id 를 사전순으로 담은 배열이고, scope 가 excluded 인 발견은 dev_only 로 갑니다.

개발 전용 의존의 결함은 배포 산출물에 실리지 않습니다. 그렇다고 무시해도 되는 것은 아니지만, 사용자에게 닿는 것과 같은 칸에 두면 정작 급한 것이 묻힙니다.

정책을 사람 말이 아니라 프로그램으로 적는다

/root/adv/gate-vuln.py 를 만드세요. python3 /root/adv/gate-vuln.py <SBOM> <자료> 로 부르면 blocking(막는 권고 id 사전순 배열)과 verdict("pass" 또는 "fail")를 담은 JSON 한 덩이를 표준 출력에 내고, 막을 것이 있으면 1 로, 없으면 0 으로 끝납니다. 정책은 '배포에 실리고(scope required) 심각도가 HIGH 또는 CRITICAL 인 발견' 입니다. 그다음 python3 /root/adv/gate-vuln.py /opt/fixtures/sbom/sbom/paygate-1.4.2.cdx.json /opt/fixtures/sbom/feeds/advisories.json 의 출력을 /root/adv/07-verdict.json 에 저장하세요.

정책이 문서에만 있으면 사람마다 다르게 읽습니다. 채점기는 이 스크립트를 다른 입력으로도 불러 봅니다 — 걸릴 것이 없는 목록에서는 0 으로 끝나야 합니다.

면제는 고칠 수 없는 것에만 준다

/root/adv/waivers.json 에 면제 세 건을 적으세요. 각 항목은 id·owner·expires·reason 이고, 세 건은 LABHUB-2026-0002(expires 2026-12-31)·LABHUB-2026-0001(expires 2026-12-31)·LABHUB-2026-0007(expires 2026-08-31)이며 owner 는 모두 payments-platform 입니다. 그다음 기준일 2026-09-11 로 면제를 적용해 /root/adv/08-verdict.json 에 as_of·waived·rejected·blocking·verdict 를 저장하세요. 면제는 기준일에 만료되지 않았고 fix_available 이 false 인 발견에만 적용되며, 거절된 것은 id 와 reason("expired" 또는 "fix_available")을 id 사전순으로 담습니다.

면제는 '아직 못 고친다' 를 기록하는 칸이지 '고치기 싫다' 를 적는 칸이 아닙니다. 고칠 판이 있는데도 면제가 통하면 그 관문은 그날부터 장식입니다.