
오픈소스 지속가능성 위기: 왜 지금 ‘공급망 리스크’로 봐야 할까?
오픈소스는 현대 소프트웨어 개발의 기반입니다. 하지만 “누구나 쓰는 만큼, 누군가가 책임지고 유지해야 하는” 구조 특성상 지속가능성(sustainability) 문제가 누적되면 곧바로 보안·운영 리스크로 전이됩니다. 오픈소스 지속가능성 이슈를 공급망 보안 관점에서 종합적으로 정리하고, 조직에서 바로 적용 가능한 정책/점검 포인트 + 자동화 예시(명령어 포함)까지 제공합니다.
개념 정리: ‘공유지의 비극’이 오픈소스에서 발생하는 방식
오픈소스는 “공공재처럼” 소비된다
- 누구나 무료로 사용 가능
- 기업 서비스·제품에도 대규모로 내장
- 결과적으로 “전 세계적으로 의존도가 높은 핵심 구성요소”가 됨
그런데 유지보수 비용은 “소수”에게 몰린다
오픈소스 프로젝트는 대체로 다음 구조를 가집니다.
- 사용자/기업: “가져다 씀”
- 메인테이너(소수): 버그 수정, 보안 패치, 릴리스, 이슈 대응, 리뷰, 문서화
즉, 혜택은 광범위하게 확산되지만 책임은 집중되면서 결국
- 번아웃(이탈)
- 지원 중단(EOL/Retire)
- 패치 지연
- 품질 저하
가 발생할 수 있습니다.
보안·운영 관점에서 핵심 리스크 유형 4가지
“지원 중단(EOL)” = “보안 패치 중단”
- 지원이 끊기면 신규 취약점이 나와도 패치가 없습니다.
- 특히 인프라 핵심(프록시/라우팅/인증/암호/패키지 매니저/빌드 도구)에서 치명적입니다.
운영 영향 예시
- 특정 오픈소스 컴포넌트가 은퇴/중단 → 마이그레이션이 “선택”이 아니라 “필수”가 됨
- 업그레이드가 늦어지면이 임시 완화책(WAF 룰/차단/설정 제한)만 계속 쌓게 됨
“버스 팩터(Bus Factor)” 리스크
- “핵심 인력이 몇 명 떠나면 프로젝트가 멈추는가?”
- 메인테이너가 1~2명인 프로젝트는 구조적으로 위험합니다.
보안 의미
- 리뷰 공백 → 취약 코드가 들어갈 확률 증가
- 패치 주기 지연 → 공격 노출 기간 증가
“프로젝트/배포 채널 악용(의도적 파괴·프로테스트웨어 등)”
- 메인테이너가 항의/갈등/압박 등으로 의도적으로 파괴적 변경을 릴리스하는 케이스가 실제로 있었습니다.
- 이는 “외부 해킹”이 아니라 “공급망 내부 변수”로 발생합니다.
운영/보안 의미
- CI에서 “latest”를 자동 반영하는 구조는 대형 장애를 유발할 수 있음
- 의존성 고정(lockfile)과 검증(서명/해시)이 중요해짐
“사회공학 기반 침투(장기 잠복 백도어)” 리스크
- 유지 역량이 약한 프로젝트는 공격자에게 좋은 표적입니다.
- “기여자로 위장 → 신뢰 확보 → 권한 확대 → 백도어 삽입” 같은 형태가 가능합니다.
보안 의미
- 코드 자체 취약점뿐 아니라 커뮤니티 거버넌스/릴리스 절차가 공격면이 됩니다.
조직이 갖춰야 할 ‘오픈소스 거버넌스’의 정답 구조
아래 6개는 “정책+자동화”로 묶어 운영하는 것이 가장 효과적입니다.
- 자산화(Inventory): 무엇을 쓰는지 목록을 만든다
- SBOM: 어디에 어떤 버전이 들어갔는지 추적 가능하게 한다
- 취약점 관리: CVE/권고가 뜨면 자동으로 감지/평가한다
- EOL/유지보수성 관리: 지원 중단/활동 저하를 조기에 탐지한다
- 무결성 검증: 서명/해시/핀ning으로 공급망 변조를 줄인다
- 배포 전 통제: CI/CD에서 차단·예외승인·완화책을 강제한다
내부 가이드/정책 문구 예시
오픈소스 사용 원칙(예시)
- “업무 시스템에 포함되는 모든 오픈소스는 자산으로 등록하며, 출처·버전·라이선스·사용 위치를 관리한다.”
- “지원 중단(EOL) 또는 유지보수 활동이 현저히 저조한 프로젝트는 신규 도입을 금지하고, 기존 사용은 대체 계획을 수립한다.”
- “서비스 핵심 구성요소(인증/암호/네트워크 경계/빌드/패키징)는 SBOM 생성 + 취약점 스캔 + 무결성 검증을 필수로 한다.”
- “외부 패키지는 기본적으로 버전 고정(pinning) 하며,
latest자동 반영을 금지한다.” - “중요 취약점은 정해진 SLA 내 패치 또는 완화 조치를 수행한다.”
실무 체크리스트: 보안 점검할 포인트
자산/SBOM
- SBOM이 자동 생성되는가?
- SBOM이 빌드 아티팩트(이미지/릴리스)와 함께 저장되는가?
- “어떤 서비스에 어떤 라이브러리가 들어갔는지” 역추적 가능한가?
취약점 대응
- CVE 발생 시 자동 알림이 오는가?
- 심각도 기준(Critical/High 등)과 처리 SLA가 정의돼 있는가?
- 패치 불가 시(업그레이드 불가) 완화 조치 템플릿이 있는가? (WAF, 설정 제한, 기능 비활성화 등)
유지보수성(EOL/활동성)
- 릴리스 주기/커밋 빈도/이슈 대응이 장기간 정지해 있지 않은가?
- 버스 팩터가 너무 낮지 않은가?
- 특정 기업/개인에 과도하게 종속되어 있지 않은가?
공급망 무결성
- 패키지 서명/해시 검증을 하는가?
- 빌드 입력(의존성)이 고정돼 재현 가능한가?
- 외부 다운로드/스크립트 실행이 과도하지 않은가?
“바로 실행 가능한” 자동화 예시
아래 예시는 “컨테이너 기반 서비스”를 기준으로 작성했지만, 원리는 동일합니다.
SBOM 생성 (Syft)
# 이미지에서 SBOM 생성 (SPDX JSON)
syft <IMAGE:TAG> -o spdx-json > sbom.spdx.json
SBOM 기반 취약점 스캔 (Grype)
# SBOM 파일을 기반으로 취약점 점검
grype sbom:sbom.spdx.json
이미지 취약점 스캔 (Trivy)
trivy image <IMAGE:TAG>
언어별 의존성 점검 예시
Node.js
npm ci
npm audit --json
Python
pip install pip-audit
pip-audit
OSV-Scanner (락파일 기반 범용 점검)
osv-scanner scan --lockfile package-lock.json
osv-scanner scan --lockfile poetry.lock
CI/CD에서 “정책 강제”하는 구성 예시 (개념+실행 흐름)
추천 파이프라인 흐름
- 빌드
- SBOM 생성
- 취약점 스캔
- 정책 판정(차단/경고/예외승인)
- 배포
정책 판정 예시
- Critical 취약점이 있고, 네트워크 노출 컴포넌트에 해당하면 배포 차단
- 특정 프로젝트가 “지원 중단” 리스트에 올라가면 배포 차단
- 예외는 보안팀 승인 + 만료일(예: 30일) 필수
운영 시나리오: “지원 중단” 컴포넌트가 발견되었을 때
- 핵심 컴포넌트(예: Ingress/프록시/암호 라이브러리)가 지원 중단 예정 또는 유지보수 정체
대응 플레이북(실무형)
- 영향 범위 식별
- 어떤 서비스/클러스터/배포에 포함되는지
- 외부 노출 여부(공격면) 확인
- 단기 완화책 적용
- 노출 축소(ACL, WAF, Rate Limit)
- 위험 기능 비활성화
- 버전 고정 및 신규 배포 중지(Freeze)
- 대체 후보 PoC
- 기능 동등성: TLS, 헤더 처리, 라우팅, 로그, 모니터링
- 보안 동등성: 인증/인가, 정책 적용, 보안 로깅 필드
- 점진적 전환
- 일부 서비스부터 전환 → 장애/성능/로그 품질 확인 → 확산
- 종료 선언일 이전 완료
- “지원 중단 이후에는 패치가 없다”가 핵심이므로, 가능한 한 그 전에 전환 완료
조직이 장기적으로 해야 할 일: “오픈소스는 보험”이라는 관점
오픈소스 지속가능성 문제는 단순 윤리·문화 이슈가 아니라, 우리 서비스의 연속성과 보안을 지키는 운영 과제입니다.
장기 전략 3트랙
- 업스트림 기여
- 코드/문서/보안 패치 기여
- 핵심 프로젝트에 대한 직접 참여는 “우리 위험을 낮추는 통제”가 될 수 있음
- 재원 지원(사용량 비례)
- 핵심 의존 프로젝트에 후원/지원 체계를 마련
- 단순 기부가 아니라 “위험 관리 비용”으로 예산화
- 거버넌스 표준화
- 도입 승인 → SBOM → 스캔 → SLA → EOL 관리 → 대체 로드맵
- 개발팀이 “막히지 않게” 하면서도 “안전 레일”을 제공
오픈소스 도입/변경 검토/승인
- 요청 정보
- 요청자/팀/시스템(서비스명)/환경(Prod/Stage)
- 요청 유형: 신규 도입 / 버전 변경 / 제거 / 대체
- 목표 일정(배포일)
- 컴포넌트 기본 정보
- 프로젝트명 / 패키지명 / 언어/런타임
- 버전(현재 → 변경 후)
- 배포 형태: 라이브러리 / 컨테이너 이미지 / Helm chart / 바이너리 등
- 사용 위치(어떤 마이크로서비스/모듈에 포함되는지)
- 도입 사유 및 영향
- 도입 이유(기능 요구, 성능, 안정화, 보안 패치 등)
- 영향 범위(사용자, 트래픽, 데이터 처리, 인증/암호 등)
- 보안/컴플라이언스 점검 결과
- SBOM 생성 여부/경로
- 취약점 스캔 결과(도구/일시/요약)
- 라이선스 종류 및 리스크 판단
- 외부 통신/권한 요구(특권, 네트워크, 파일 접근 등)
- 공급망 무결성(서명/해시 검증, 버전 핀ning, lockfile 여부)
- 유지보수성 평가
- 릴리스 주기/최근 업데이트
- 버스 팩터(핵심 유지 인력)
- EOL/지원 중단 일정 존재 여부
- 결론 및 조건
- 승인/조건부 승인/반려
- 조건부 승인 시 조건(예: “30일 내 업그레이드”, “WAF 룰 적용”, “예외 만료일”)
- 결재 라인
- 개발 리드 / 보안 / 운영 / (필요 시) 법무
취약점 처리 SLA(심각도별 조치/예외 승인/만료 규정 포함)
취약점 관리는 “스캔 도구 도입”이 끝이 아니라,
- 언제까지
- 누가
- 어떤 수준으로
- 패치가 어려우면 어떻게 예외를 처리할지
를 정하는 운영 규칙입니다.
SLA가 없으면 취약점은 영구 백로그가 되고, 결국 감사/사고 때 “관리 부재”로 보입니다.
SLA 설계의 핵심 원칙(추천)
- “심각도”만 보지 말고 노출도(인터넷 노출/권한/데이터 민감도)를 같이 봅니다.
- 패치가 불가하면 “예외 승인”이 아니라 완화조치 + 만료일이 필수입니다.
- 예외는 반드시 “재평가/재승인” 구조로 만들고, 자동 알림이 있어야 합니다.
심각도별 처리 기준(예시 표)
아래는 많이 쓰는 현실적 예시입니다.
- Critical
- 목표: 24~72시간 내 조치(패치/업그레이드/차단/비활성화)
- 최소 조치: 인터넷 노출이면 우선 완화(ACL/WAF/기능 차단)부터
- 예외: 원칙적 금지(불가피하면 임원급 승인 + 7~14일 내 만료)
- High
- 목표: 7일 내 조치
- 예외: 30일 이내 만료를 기본으로, 반드시 완화책 명시
- Medium
- 목표: 30일 내
- 예외: 90일 만료, 분기 단위 재평가
- Low
- 목표: 90일 내 또는 정기 배치
- 예외: 장기 예외 가능하나 “기능 미사용/노출 없음” 근거 필수
팁: “운영 현실” 때문에 무조건 짧게 잡으면 문서가 무력화됩니다.
대신 Critical/High에 집중하고, Medium/Low는 정기 릴리스와 결합하세요.
예외 승인(waiver) 프로세스(설명식)
예외는 “패치를 안 한다”가 아니라 “패치를 미루는 동안 위험을 통제한다”입니다.
예외 신청서에 반드시 들어갈 것
- 취약점 ID/CVE, 영향 버전
- 패치 불가 사유(호환성/벤더 미지원/다운타임 등)
- 완화 조치(필수): WAF 룰, 기능 비활성화, 접근 통제, 권한 제거, 모니터링 강화
- 만료일(필수): 7/30/90일 등
- 재평가 계획: “업그레이드 가능 시점”, “대체 컴포넌트 검토 일정”
승인 권한(예시)
- Critical 예외: CISO/보안책임자 + 서비스 오너 공동 승인
- High 예외: 보안팀장 + 개발리드
- Medium/Low: 보안 담당자 승인 + 기록
리포팅(운영 관점)
- 주간: “Critical/High 오픈 건수 + SLA 위반 건수 + 예외 만료 임박”
- 월간: “서비스별 취약점 트렌드, 반복 발생 원인(의존성 관리 미흡 등)”
EOL/지원중단 대응 플레이북(운영+보안 합동)
EOL은 단순 “지원 종료”가 아니라
- 보안 패치 공급 중단
- 새 취약점 발생 시 대응 불가
- 장애 발생 시 커뮤니티/벤더 지원 부재
를 의미합니다.
즉, EOL은 “취약점”보다 더 구조적인 위험이라 사전에 강제 로드맵이 필요합니다.
1단계) 식별(Identify)
- EOL 대상: 프로젝트/버전/사용 서비스 목록
- 사용 범위: Prod 포함 여부, 외부 노출 여부
- 대체 가능성: 업그레이드/대체 솔루션 존재 여부
2단계) 위험평가(Assess)
- 노출도: 인터넷 노출? 인증/암호 경로? 데이터 처리?
- 의존도: 제거 불가 핵심인가? 대체 비용은?
- 운영 영향: 다운타임/성능/호환성
3단계) 단기 완화(Contain)
EOL 즉시 제거가 어렵다면 임시 통제를 정의합니다.
- 접근통제(ACL/VPN/관리망)
- 기능 비활성화(취약 기능 off)
- WAF/Rate limit 적용
- 모니터링 강화(탐지 룰/알림 기준 상향)
4단계) 전환 계획(Migrate Plan)
- 대체 후보 선정 기준(기능 동등성 + 보안 동등성 + 운영성)
- PoC 범위와 성공 기준
- 전환 일정(Blue/Green, 카나리)
- 롤백 플랜
5단계) 실행(Migrate)
- 일부 서비스부터 점진 전환
- 로그/성능/장애율/보안 이벤트 모니터링
- 완료 후 잔존 사용 0% 확인
6단계) 종료(Closeout)
- 제거 증빙(배포 목록, 이미지/차트 버전 제거)
- 정책 업데이트(재발 방지: 신규 도입 차단 룰 추가)
역할 분담(RACI 예시)
- 운영팀: 서비스 영향/배포/롤백/가용성
- 보안팀: 위험평가/완화책/예외 승인/모니터링 기준
- 개발팀: 코드 변경/호환성 수정/테스트
- (필요 시) 구매/법무: 상용 대체 솔루션 계약, 라이선스 검토
CI 정책 룰 예시(차단 기준/예외 기준/리포팅 형식)
CI 정책 룰은 “사람이 매번 체크”하는 걸 자동화해,
- 위험한 빌드가 Prod로 못 나가게 막고
- 예외는 기록과 만료로 관리하며
- 결과는 표준 형식으로 공유되게 합니다.
아래는 실무에서 바로 쓰기 좋은 차단 기준(Policy Gate) 예시입니다.
취약점 기반 차단
- Critical 존재 AND 외부 노출 구성요소 포함 → 빌드 실패
- High 이상이 특정 개수 이상 → 실패(예: High ≥ 5)
- KEV(실제 악용) 목록에 포함된 취약점 존재 → 실패
EOL 기반 차단
- EOL 대상 프로젝트/버전이 SBOM에 포함 → 실패
- 지원 중단 예정이 90일 이내인 컴포넌트 포함 → 경고 또는 실패(조직 정책에 따라)
무결성/의존성 기반 차단
- lockfile 미존재(핀ning 불가) → 실패
latest태그 사용 → 실패- 서명 검증 불가한 레포/아티팩트 사용 → 실패(또는 경고)
예외 기준
예외는 “통과 버튼”이 아니라 “조건부 통과 계약서”입니다.
예외 허용 조건(권장)
- 완화 조치가 명시되어 있고
- 만료일이 있으며(필수)
- 추적 ID(승인서/티켓)가 있고
- 범위가 제한돼야 합니다(특정 서비스/특정 버전/특정 기간)
예외 예시
- “High 취약점 1건은 해당 기능을 사용하지 않음이 증명됨 + 설정으로 비활성화 + 30일 만료”
리포팅 형식(표준 출력 예시)
CI 결과를 팀이 바로 읽게 하려면 “정형화”가 중요합니다.
리포트 필드(추천)
- 빌드 ID / 커밋 / 서비스명 / 환경
- SBOM 링크(저장 위치)
- 취약점 요약: Critical/High/Medium/Low 개수
- 차단 사유(룰 ID)
- 예외 적용 여부 및 만료일
- 조치 권고(업그레이드 버전, 대체 패키지)
파이프라인 예시(개념 + 실행 커맨드)
아래는 “컨테이너 이미지” 기준입니다.
# 1) 빌드
docker build -t mysvc:${GIT_SHA} .
# 2) SBOM 생성
syft mysvc:${GIT_SHA} -o spdx-json > sbom.spdx.json
# 3) 취약점 스캔
grype sbom:sbom.spdx.json -o json > vuln.json
# 4) 정책 판정(사내 스크립트/룰 엔진)
python policy_gate.py --vuln vuln.json --sbom sbom.spdx.json --policy policy.yaml
정책 파일(policy.yaml)은 이런 식의 룰을 가질 수 있습니다. (개념 예시)
deny_if_critical_over_0: truedeny_if_high_over: 5deny_if_eol_component_found: truedeny_if_latest_tag: trueallow_with_waiver: requires(expiry<=30d, mitigation=true, ticket=true)
댓글