🔥 패키지 컬렉션 보호하기
288자
4분
Swift Package Manager는 패키지 컬렉션의 보안을 강화하기 위해 서명 기능을 제공하고 있어요. 하지만 서명만으로는 다음과 같은 공격 벡터를 완벽히 방어할 수 없답니다:
- 서명 제거: 공격자가 서명된 컬렉션에서 서명을 제거하면 unsigned collection으로 다운로드되어 서명 검사를 우회할 수 있어요.
- 서명 교체: 공격자가 컬렉션을 수정한 후 다른 인증서로 다시 서명하면 서명이 유효한 한 SwiftPM이 이를 받아들일 수 있죠.
이러한 공격에 대비하기 위해 SwiftPM은 컬렉션 제작자가 다음과 같은 작업을 할 수 있도록 인증서 고정(certificate-pinning) 설정을 제공합니다:
- 컬렉션에 대한 서명 검사 필수화 — "서명 제거" 공격 방어
- 서명에 사용할 수 있는 인증서 제한 — "서명 교체" 공격 방어
컬렉션 제작자가 인증서 고정 설정을 정의하는 과정은 다음과 같아요:
PackageCollectionSourceCertificatePolicy
파일을 수정하여defaultSourceCertPolicies
딕셔너리에 새 항목을 추가하세요:
private static let defaultSourceCertPolicies: [String: CertificatePolicyConfig] = [ // 패키지 컬렉션 URL의 "host" 부분을 키로 사용합니다. // 이 도메인에 호스팅된 모든 패키지 컬렉션에 서명이 필요합니다. "www.example.com": CertificatePolicyConfig( // 서명 인증서는 반드시 이 subject user ID를 가져야 합니다. certPolicyKey: CertificatePolicyKey.default(subjectUserID: "exampleUserID"), /* 인증서의 base64 인코딩 문자열을 계산하려면: let certificateURL = URL(fileURLWithPath: <DER로 인코딩된 루트 인증서 파일 경로>) let certificateData = try Data(contentsOf: certificateURL) let base64EncoodedCertificate = certificateData.base64EncodedString() */ base64EncodedRootCerts: ["<base64로 인코딩된 루트 인증서>"] ) ]
swift
- Pull Request를 열어 검토를 요청하세요. 요청자는 자신의 신원과 도메인 소유권을 증명할 수 있어야 해요:
- 요청자는 실제 인증서 파일(DER로 인코딩됨)을 제공해야 해요. SwiftPM 팀은 인증서 체인이 유효하고 PR에 제공된 값이 올바른지 확인할 거예요.
- 요청자는 Pull Request를 참조하는 TXT 레코드를 추가해야 해요. SwiftPM 팀은
dig -t txt <DOMAIN>
명령을 실행하여 이를 확인할 거예요. 이는 도메인 소유권 증명 역할을 하죠.
- 변경 사항이 승인되면 다음 SwiftPM 릴리스에 반영될 거예요.
인증서 고정 설정은 웹 도메인과 연결되므로, 웹에 호스팅된(즉, URL이 https://
로 시작하는) 서명된 컬렉션에만 적용할 수 있어요. 로컬 파일 시스템에서 발견된(즉, URL이 file://
로 시작하는) 컬렉션에는 적용되지 않습니다.