[Accepted] PEP 458 - Secure PyPI downloads with signed repository metadata
원문 링크: PEP 458 - Secure PyPI downloads with signed repository metadata
상태: Accepted 유형: Standards Track 작성일: 27-Sep-2013
PEP 458은 PyPI(Python Package Index) 다운로드의 보안 강화를 위한 제안서입니다. 이 PEP는 사용자가 PyPI에서 유효한 패키지를 다운로드할 수 있도록 PyPI 인프라에 필요한 변경 사항을 설명합니다. 특히, The Update Framework (TUF)를 PyPI에 통합하여 패키지 무결성, 일관성, 최신성을 보장하고, PyPI 또는 서명 키(signing keys)의 손상 시 복구 메커니즘을 제공하는 데 중점을 둡니다.
PEP 458: 서명된 저장소 메타데이터를 통한 PyPI 다운로드 보안 강화
개요
이 PEP는 PyPI 사용자가 유효한 패키지를 얻도록 보장하기 위해 PyPI 인프라에 필요한 변경 사항을 설명합니다. 이러한 변경 사항은 생태계의 다른 부분에 최소한의 영향을 미칠 것입니다. 이 PEP는 PyPI와 사용자 간의 통신에 중점을 두므로, 패키지 개발자의 별도 조치는 필요하지 않습니다. 개발자는 현재와 동일한 프로세스를 사용하여 패키지를 업로드하며, PyPI는 이 패키지에 대한 서명된 저장소 메타데이터(signed repository metadata)를 자동으로 생성합니다.
보안 메커니즘이 효과적이려면, pip와 같은 PyPI 클라이언트(consumer)가 PyPI에서 제공하는 서명과 메타데이터를 검증하기 위한 추가적인 작업을 수행해야 합니다. 이 검증 과정은 사용자에게 투명하게 제공될 수 있으며(실패하지 않는 한) 자동 보안 메커니즘을 제공합니다.
제안된 TUF 통합 (Proposed TUF Integration)
이 PEP는 The Update Framework (TUF)를 Python Package Index (PyPI)에 통합하는 방법을 제안합니다. TUF는 소프트웨어 업데이터 또는 패키지 매니저를 위한 유연한 보안 추가 기능으로 설계되었습니다. TUF의 전체 구현은 역할 책임 분리, 다수 서명 규칙(many-man rule) 채택, 서명 키 오프라인 보관, 만료되거나 손상된 서명 키 철회와 같은 최신 보안 관행을 통합합니다.
이 PEP에서 제안하는 초기 통합은 pip와 같은 최신 패키지 매니저가 PyPI 미러 및 PyPI 자체의 콘텐츠 배포 네트워크(CDN)에 대한 공격에 더욱 안전해지고, 이러한 공격으로부터 사용자를 더 잘 보호할 수 있도록 합니다. 특히, 이 PEP는 TUF 메타데이터를 생성하고 통합하기 위해 PyPI 프로세스를 어떻게 조정해야 하는지 설명합니다(최소 보안 모델). 이 최소 보안 모델은 PyPI에 저장된 키로 서명된 PyPI 배포본의 검증을 지원합니다.
비목표 (Non-goals) 이 PEP는 PyPI의 기존 기능을 제거하지 않습니다. 특히, OpenPGP 서명에 대한 기존 지원을 대체하지 않습니다. 개발자는 계속해서 배포본과 함께 분리된 OpenPGP 서명을 업로드할 수 있습니다.
PEP 현황 (PEP Status)
이 PEP를 구현하는 데 필요한 작업량으로 인해, 2019년 초에 적절한 자금이 확보될 때까지 연기되었습니다. Python Software Foundation(PSF)은 이 자금을 확보했고, 새로운 PEP 공동 저자들이 PEP 논의를 재개했습니다.
동기 (Motivation)
소프트웨어 저장소에 대한 공격은 일반적이며, 심지어 매우 우수한 보안 관행을 가진 조직에서도 발생합니다. 이러한 저장소 손상은 공격자가 저장소에 저장된 모든 파일을 편집하고 저장소에 있는 모든 키(온라인 키)를 사용하여 이 파일에 서명할 수 있도록 허용합니다. 많은 서명 체계(TLS와 같은)에서 이러한 접근은 공격자가 저장소의 파일을 교체하고 이 파일이 PyPI에서 온 것처럼 보이게 할 수 있도록 합니다. 신뢰할 수 있는 개인 키를 철회하고 교체할 방법이 없으면 저장소 손상으로부터 복구하기가 매우 어렵습니다.
2013년 1월 5일, Python Software Foundation (PSF)은 Python 및 Jython wiki에서 보안 침해가 발생했다고 발표했습니다. 이로 인해 모든 위키 데이터가 파괴되었습니다. 다행히 PyPI 인프라는 이 침해의 영향을 받지 않았지만, 이 사건은 PyPI가 침해 발생 시 사용자를 최대한 보호하기 위한 방어 조치를 취해야 한다는 점을 상기시켜 주었습니다.
이전에는 PyPI가 MD5 해시를 사용하여 패키지 매니저에게 배포 파일이 전송 중에 손상되었는지 여부를 알렸습니다. 그러나 SSL 부재로 인해 패키지 매니저가 PyPI로의 전송 무결성을 확인하기 어려웠습니다. 따라서 pip와 PyPI 사이에서 중간자 공격(man-in-the-middle attack)을 쉽게 시작하고 배포본의 내용을 임의로 변경할 수 있었습니다.
이 PEP는 PEP 480의 후속 제안과 함께 PyPI 사용자를 PyPI 패키지의 무결성, 일관성 및 최신성 속성 손상으로부터 보호하고, 키 위험을 완화하며 PyPI 또는 서명 키 손상으로부터 복구할 수 있는 메커니즘을 제공하여 침해 탄력성을 강화하는 것을 목표로 합니다.
위협 모델 (Threat Model)
위협 모델은 다음을 가정합니다:
- 오프라인 키는 안전하게 저장됩니다.
- 공격자는 PyPI의 온라인에 저장된 신뢰할 수 있는 키를 손상시킬 수 없습니다.
- 공격자는 클라이언트 요청에 응답할 수 있습니다.
이 위협 모델은 최소 보안 모델을 설명합니다. PEP 480에서 설명하는 최대 보안 모델은 공격자가 PyPI의 온라인 키를 손상시킬 수 있다고 가정합니다.
정의 (Definitions)
이 PEP에서 사용되는 주요 용어는 다음과 같습니다:
- Role (역할): TUF는 하나의 Root Role과 그 Root Role이 직간접적으로 책임을 위임하는 여러 다른 Role을 지정합니다.
- Distribution file (배포 파일): Python 패키지, 모듈 및 기타 리소스 파일이 포함된 버전 관리되는 아카이브 파일.
- Target files (대상 파일): 일반적으로 PyPI의 모든 파일로, TUF로 무결성이 보장되어야 합니다.
- Metadata (메타데이터): Role, 다른 메타데이터 및 대상 파일을 설명하는 서명된 파일.
- Repository (저장소): 명명된 메타데이터 및 대상 파일의 소스.
- Consistent snapshot (일관된 스냅샷): PyPI의 모든 프로젝트의 완전한 상태를 특정 시점에 포착하는 TUF 메타데이터 및 대상 파일 세트.
- Online key (온라인 키): PyPI 서버 인프라에 저장되어야 하는 개인 암호화 키.
- Offline key (오프라인 키): PyPI 서버 인프라와 독립적으로 저장되어야 하는 개인 암호화 키.
- Threshold signature scheme (임계값 서명 체계): Role은 n개의 키 중 최소 t개가 메타데이터에 서명해야 한다고 지정함으로써 키 손상에 대한 탄력성을 높일 수 있습니다.
TUF 개요 (Overview of TUF)
가장 높은 수준에서 TUF는 애플리케이션에 파일의 새 버전을 파악하고 얻는 안전한 방법을 제공합니다. TUF는 저장소에 서명된 메타데이터(저장소의 파일을 설명하는 텍스트 파일)를 추가하고 업데이트 절차 중에 메타데이터 파일을 참조함으로써 공격을 해결하도록 설계되었습니다. 저장소 파일은 소프트웨어 업데이트 시스템으로 전달되기 전에 메타데이터에 포함된 정보에 대해 검증됩니다. 이 프레임워크는 또한 다중 서명 신뢰(multi-signature trust), 암호화 키의 명시적 및 암묵적 철회(explicit and implicit revocation), 메타데이터의 책임 분리, 최소화된 키 위험을 제공합니다.
PyPI와 TUF 통합 (Integrating PyPI with TUF)
소프트웨어 업데이트 시스템이 TUF와 통합하려면 두 가지 주요 작업을 완료해야 합니다. 첫째, 서버 측의 저장소가 서명된 TUF 메타데이터를 제공하도록 수정되어야 합니다. 이 PEP는 통합의 첫 번째 부분과 TUF를 통한 소프트웨어 업데이트를 지원하기 위해 PyPI에 필요한 변경 사항을 다룹니다. 둘째, 업데이트 시스템의 클라이언트 측에 프레임워크를 추가해야 합니다. 예를 들어, TUF는 pip 패키지 매니저와 통합될 수 있습니다.
PyPI에 필요한 추가 저장소 파일 (What Additional Repository Files are Required on PyPI?)
pip와 같은 패키지 매니저가 TUF로 배포본을 다운로드하고 검증하려면, PyPI에 몇 가지 추가 파일이 추가되어야 합니다. 이 추가 저장소 파일을 TUF 메타데이터라고 하며, 어떤 키를 신뢰할 수 있는지, 파일의 암호화 해시, 서명, 메타데이터 버전 번호, 메타데이터가 만료되어야 하는 날짜와 같은 정보를 포함합니다.
PyPI와 TUF 메타데이터 (PyPI and TUF Metadata)
TUF 메타데이터는 클라이언트가 업데이트 결정을 내리는 데 사용할 수 있는 정보를 제공합니다. 예를 들어, targets
메타데이터는 PyPI에서 사용 가능한 대상 파일을 나열하고 각 파일에 필요한 서명, 암호화 해시 및 파일 크기를 포함합니다.
TUF는 4가지 최상위 역할(top-level roles)을 요구합니다: root
, timestamp
, snapshot
, targets
.
root
역할: 전체 저장소의 신뢰의 중심입니다. 다른 최상위 역할의 공개 암호화 키를 지정합니다.timestamp
역할: 최신snapshot
을 참조하며, 저장소의 새snapshot
이 사용 가능할 때를 나타낼 수 있습니다.snapshot
역할: 모든 TUF 메타데이터 파일(timestamp 제외)의 최신 버전을 나타냅니다.targets
역할: 사용 가능한 대상 파일의 파일 경로와 암호화 해시를 나열합니다.
메타데이터 서명 및 저장소 관리 (Signing Metadata and Repository Management)
가장 자주 변경되는 역할은 timestamp
, snapshot
, 그리고 bins
에 의해 위임된 역할(bin-n
)입니다. timestamp
및 snapshot
메타데이터는 root
, targets
또는 위임된 메타데이터가 업데이트될 때마다 업데이트되어야 합니다.
PyPI 관리자는 매년 root
및 targets
역할 키에 서명해야 합니다. 자동화는 모든 프로젝트의 타임스탬프 스냅샷에 지속적으로 서명할 것입니다.
PyPI Root Keys의 초기 신뢰 설정 방법 (How to Establish Initial Trust in the PyPI Root Keys)
pip와 같은 패키지 매니저는 사용자가 처음 다운로드하는 설치 파일과 함께 root
메타데이터 파일을 제공해야 합니다. 이는 모든 최상위 역할(자체 root
키 포함)에 대해 신뢰할 수 있는 키에 대한 정보를 포함합니다. 패키지 매니저는 또한 TUF 클라이언트 라이브러리를 번들로 제공해야 합니다.
최소 보안 모델 (Minimum Security Model)
이 PEP에서 제안하는 것은 PyPI에 저장된 개인 암호화 키로 서명된 PyPI 배포본의 검증을 지원하는 최소 보안 모델입니다. 개발자가 업로드한 배포본은 PyPI에서 서명되며 즉시 다운로드 가능합니다.
최소 보안 모델은 개발자로부터 아무런 조치도 요구하지 않으며 악의적인 CDN 및 공용 미러로부터 보호합니다. 업로드된 배포본의 지속적인 배포(continuous delivery)를 지원하기 위해 PyPI는 온라인 키로 프로젝트에 서명합니다. 이 수준의 보안은 프로젝트가 미러 또는 CDN에 의해 우발적으로 또는 의도적으로 조작되는 것을 방지합니다.
메타데이터 만료 시간 (Metadata Expiry Times)
root
, targets
, bins
역할의 메타데이터는 변경될 가능성이 매우 낮으므로 1년에 한 번 만료되어야 합니다. timestamp
, snapshot
, bin-n
메타데이터는 CDN 또는 미러가 매일 PyPI와 동기화되어야 하므로 매일 만료되어야 합니다.
메타데이터 확장성 (Metadata Scalability)
저장소의 프로젝트 및 배포본 수가 증가함에 따라 TUF 메타데이터도 그에 비례하여 증가해야 합니다. 이 PEP는 세부 사항을 다루지 않지만, TUF는 큰 targets
메타데이터 파일을 여러 작은 파일로 분할하는 “해시된 빈 위임(hashed bin delegation)” 체계를 특징으로 합니다.
PyPI 및 키 요구 사항 (PyPI and Key Requirements)
권장되는 키의 수 및 유형 (Number and Type Of Keys Recommended)
root
역할 키는 보안에 매우 중요하며 매우 드물게 사용되어야 합니다. 주로 키 철회에 사용되며, 전체 PyPI의 신뢰의 중심입니다. root
역할은 각 최상위 역할에 대해 승인된 키(자체 키 포함)에 서명합니다.
targets
역할은 모든 대상의 bins
역할에 대한 정적 위임에만 서명하는 데 사용됩니다. 키 관리의 단순성을 위해 targets
역할의 키는 생성되어 역할에 서명하는 데 사용되는 즉시 영구적으로 폐기하는 것이 좋습니다.
timestamp
, snapshot
, 그리고 모든 bin-n
역할의 키는 지속적인 배포를 지원하기 위해 온라인 상태여야 합니다.
온라인 키 관리 (Managing online keys)
timestamp
, snapshot
, 그리고 모든 bin-n
역할이 공유하는 온라인 키는 Python 인프라에 암호화되거나 암호화되지 않은 상태로 저장될 수 있습니다. 이 온라인 키의 사용은 신중하게 로깅, 모니터링 및 감사되어야 합니다.
오프라인 키 관리 (Managing offline keys)
root
, targets
, bins
역할 키는 최대 보안을 위해 오프라인 상태여야 합니다. 즉, 개인 키는 PyPI에 저장되어서는 안 됩니다. 이 키를 생성, 백업 및 저장하는 오프라인 키 의식(offline key ceremony)이 있어야 합니다.
메타데이터 생성 방법 (How Should Metadata be Generated?)
일관된 스냅샷 (Consistent Snapshots)
PyPI의 TUF 메타데이터를 매우 불안정한 대상 파일과 일관되게 유지하려면 일관된 스냅샷(consistent snapshots)을 사용해야 합니다. 각 일관된 스냅샷은 주어진 시점의 알려진 모든 프로젝트의 상태를 포착하며, 다른 스냅샷에 영향을 미치지 않고 다른 스냅샷과 안전하게 공존하거나 독립적으로 삭제될 수 있습니다.
일관된 스냅샷을 유지하려면, 모든 TUF 메타데이터는 디스크에 기록될 때 파일 이름에 버전 번호를 포함해야 합니다: VERSION_NUMBER.ROLENAME.json
.
대상 파일을 일관된 스냅샷의 일부로 표시하려면, 디스크에 기록될 때 파일 이름에 해당 해시를 포함해야 합니다: HASH.FILENAME
.
일관된 스냅샷 생성 (Producing Consistent Snapshots)
새로운 배포 파일이 PyPI에 업로드되면, PyPI는 담당 bin-n
메타데이터를 업데이트해야 합니다. PyPI는 또한 업데이트된 bin-n
메타데이터를 반영하도록 snapshot
을 업데이트하고, 업데이트된 snapshot
메타데이터를 반영하도록 timestamp
를 업데이트해야 합니다. 이러한 업데이트는 자동화된 스냅샷 프로세스에 의해 처리되어야 합니다.
오래된 메타데이터 정리 (Cleaning up old metadata)
새로운 일관된 스냅샷의 지속적인 생성으로 인해 디스크 공간이 부족해지는 것을 방지하기 위해 PyPI는 오래된 일관된 스냅샷, 즉 과거의 합리적인 시간(예: 1시간)에 더 이상 사용되지 않는 메타데이터 및 대상 파일을 정기적으로 삭제해야 합니다.
root
메타데이터는 버전 관리되지만 어떤 일관된 스냅샷의 일부도 아닙니다. PyPI는 root
메타데이터의 이전 버전을 삭제해서는 안 됩니다. 이는 클라이언트가 로컬 root
메타데이터가 얼마나 오래되었는지에 관계없이 최신 root
역할 키로 업데이트할 수 있도록 보장합니다.
프로젝트 및 배포본 신뢰 철회 (Revoking Trust in Projects and Distributions)
때때로 프로젝트 또는 배포본을 철회해야 할 때가 있습니다. 프로젝트 또는 배포본에 대한 신뢰를 철회하려면, 관련 bin-n
역할은 해당 대상(targets)을 제거하고 bin-n
메타데이터를 다시 서명하면 됩니다. 이 작업은 온라인 bin-n
키를 통해서만 수행됩니다.
키 손상 분석 (Key Compromise Analysis)
이 PEP는 최소 보안 모델, 배포본의 지속적인 배포를 지원하기 위해 추가되어야 하는 TUF 역할, 그리고 각 역할에 대한 메타데이터를 생성하고 서명하는 방법을 다룹니다.
키 손상 발생 시 (In the Event of a Key Compromise)
timestamp
, snapshot
, targets
, bins
또는 bin-n
키 중 임계값 수가 손상되면 PyPI는 다음 단계를 수행해야 합니다.
root
역할에서timestamp
,snapshot
,targets
역할 키를 철회합니다.targets
역할에서bins
키를 철회합니다.- 새로운
targets
역할 메타데이터에 서명하고 새로운 키를 폐기합니다. - 모든
bin-n
역할의 대상(targets)을 마지막으로 알려진 유효한 일관된 스냅샷과 비교하여 무결성을 확인합니다. bins
메타데이터에서bin-n
대상의 키를 갱신합니다.- 새로운 타임스탬프가 지정된 일관된 스냅샷을 발행합니다.
root
키의 임계값 수가 손상되면, PyPI는 위 단계를 수행하고 root
역할의 모든 root
키도 교체해야 합니다.
스냅샷 감사 (Auditing Snapshots)
악의적인 당사자가 PyPI를 손상시키면 온라인 키로 임의의 파일에 서명할 수 있습니다. 오프라인 키를 가진 역할(즉, root
, targets
, bins
)은 여전히 보호됩니다. 저장소 손상으로부터 안전하게 복구하려면, 스냅샷을 감사하여 파일이 신뢰할 수 있는 버전으로만 복원되도록 해야 합니다.
업데이트 프로세스의 향후 변경 사항 관리 (Managing Future Changes to the Update Process)
업데이트 프로세스에 호환되지 않는 변경 사항이 발생하면 PyPI는 기존 클라이언트에 지장을 주지 않고 이러한 변경 사항을 구현해야 합니다.
이 PEP의 PyPI에 대한 변경 사항은 역호환됩니다. 대상 파일 및 Simple index의 위치는 이 PEP에서 변경되지 않으므로, 기존 PyPI 클라이언트는 이러한 파일을 사용하여 계속 업데이트를 수행할 수 있습니다. 이 PEP는 클라이언트가 TUF 메타데이터를 사용하여 업데이트 프로세스의 보안을 향상시키는 기능을 추가합니다.
해시 알고리즘 전환 계획 (Hash Algorithm Transition Plan)
대상 및 메타데이터 파일을 해시하는 데 사용되는 알고리즘이 취약해지면, 더 강력한 해시 알고리즘으로 대체해야 합니다. TUF 메타데이터 형식은 다른 해시 알고리즘의 다이제스트를 알고리즘 식별자와 함께 나란히 나열할 수 있으므로 클라이언트는 알고리즘 간에 원활하게 전환할 수 있습니다.
부록 A: TUF로 방지되는 저장소 공격 (Appendix A: Repository Attacks Prevented by TUF)
TUF는 다음과 같은 다양한 저장소 공격을 방지합니다:
- 임의 소프트웨어 설치 (Arbitrary software installation): 공격자가 클라이언트 시스템에 원하는 모든 것을 설치합니다.
- 롤백 공격 (Rollback attacks): 공격자가 클라이언트가 이미 본 파일보다 오래된 파일을 소프트웨어 업데이트 시스템에 제공하여 클라이언트가 오래된 파일을 사용하게 합니다.
- 무기한 정지 공격 (Indefinite freeze attacks): 공격자가 클라이언트가 이미 본 동일한 파일을 계속 소프트웨어 업데이트 시스템에 제공하여 클라이언트가 새 파일이 있음을 알지 못하게 합니다.
- 끝없는 데이터 공격 (Endless data attacks): 공격자가 파일 다운로드 요청에 끝없는 데이터 스트림으로 응답하여 클라이언트에 피해를 줍니다.
- 느린 검색 공격 (Slow retrieval attacks): 공격자가 클라이언트에 매우 느린 데이터 스트림으로 응답하여 클라이언트가 업데이트 프로세스를 계속할 수 없게 합니다.
- 불필요한 종속성 공격 (Extraneous dependencies attacks): 공격자가 클라이언트에게 원하는 소프트웨어를 설치하려면 관련 없는 소프트웨어도 설치해야 한다고 지시합니다.
- 혼합 및 매치 공격 (Mix-and-match attacks): 공격자가 클라이언트에게 저장소에 동시에 존재하지 않았던 파일이 포함된 저장소 보기를 제공합니다.
- 잘못된 소프트웨어 설치 (Wrong software installation): 공격자가 클라이언트에게 클라이언트가 원하지 않는 신뢰할 수 있는 파일을 제공합니다.
- 악의적인 미러가 업데이트를 방지하는 공격 (Malicious mirrors preventing updates): 하나의 저장소 미러를 제어하는 공격자가 사용자가 다른 좋은 미러에서 업데이트를 얻는 것을 방지할 수 있습니다.
- 키 손상에 대한 취약성 (Vulnerability to key compromises): 단일 키 또는 주어진 임계값 미만의 키를 손상시킬 수 있는 공격자가 클라이언트를 손상시킬 수 있습니다.
결론 및 파이썬 사용에 미치는 영향
PEP 458은 PyPI의 보안을 획기적으로 강화하기 위한 중요한 단계입니다. TUF의 도입은 개발자에게는 추가적인 부담 없이, 사용자에게는 훨씬 안전한 패키지 다운로드 환경을 제공할 것입니다.
- 개발자: 기존 패키지 업로드 프로세스를 그대로 유지합니다. PyPI가 자동으로 서명된 메타데이터를 생성하므로, 개발자는 별도의 조치를 취할 필요가 없습니다.
- 사용자 및 클라이언트(pip 등): pip와 같은 패키지 매니저는 TUF 메타데이터를 활용하여 다운로드하는 패키지의 무결성과 신뢰성을 검증하게 됩니다. 이 과정은 대부분 사용자에게 투명하게 이루어지지만, 만약 검증에 실패하면 사용자에게 보안 경고를 제공할 것입니다. 이를 통해 악의적인 미러, CDN 공격, 중간자 공격 등으로부터 사용자를 효과적으로 보호할 수 있습니다.
전반적으로 이 PEP는 파이썬 패키지 생태계의 신뢰성을 높이고, 소프트웨어 공급망 공격에 대한 방어력을 강화하는 데 크게 기여할 것입니다.
⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.
Comments