Package URL
Package URL(purl)은 소프트웨어 패키지를 생태계, 네임스페이스, 이름, 버전으로 식별하는 표준 문자열입니다. 예: pkg:npm/[email protected].
최종 업데이트: 2026년 11월 11일
Package URL(purl, 표준화된 패키지 식별자)은 소프트웨어 패키지를 그 패키지의 생태계가 부르는 방식 그대로 나타내는 식별자입니다: pkg:type/namespace/name@version?qualifiers#subpath. 2025년 12월에 Ecma 표준 ECMA-427(초판, Ecma TC54)이 되었으며, 사양은 package-url/purl-spec에서 관리됩니다.
purl의 구성
모든 purl은 스킴 pkg로 시작합니다. 타입은 생태계 또는 패키지 관리자입니다(npm, pypi, cargo, deb, maven 등). 네임스페이스는 선택적인 그룹으로, npm 스코프, Maven 그룹, 리눅스 배포판 등이 들어갑니다. 그다음이 이름과 버전입니다. 한정자는 아키텍처나 배포판 릴리스처럼 생태계가 정확한 패키지를 특정하는 데 필요한 정보를 더하고, 하위 경로는 패키지 내부의 위치를 가리킵니다.
pkg:npm/%40angular/[email protected]
pkg:pypi/[email protected]
pkg:cargo/[email protected]
pkg:deb/ubuntu/[email protected]+dfsg-1ubuntu2.1?arch=arm64&distro=noble
마지막 예시는 "cpio 2.15" 이상의 정보를 담고 있습니다. Ubuntu가 Noble 릴리스의 arm64용으로 직접 빌드한 패키지라는 뜻입니다. 배포판은 보안 수정을 자체 버전에 백포트하기 때문에, 같은 업스트림 버전이라도 한 배포판에서는 취약하고 다른 배포판에서는 수정되어 있을 수 있으므로 이 정보가 중요합니다.
취약점 매칭이 purl에 의존하는 이유
패키지 단위로 정리된 보안 권고 데이터베이스는 구성 요소를 생태계와 이름으로 파악합니다. OSV 스키마는 영향을 받는 모든 패키지에 ecosystem과 name을 필수로 요구하고, purl 필드를 "선택 사항이지만 권장"으로 규정합니다. GitHub의 권고도 생태계 패키지 단위로 등록됩니다. SBOM 구성 요소에 purl이 있으면 도구가 이를 해당 권고와 정확히 매칭할 수 있습니다. purl이 없으면 이름이나 CPE로 추측해야 하거나 아무것도 매칭하지 못하고, 그 취약점은 보고되지 않습니다.
우리가 비교한 Yocto 빌드에서는 빌드 시스템 자체의 SBOM이 수백 개의 Rust 크레이트를 다운로드 위치가 붙은 .crate 파일로만 기재했고 pkg:cargo purl이 없었기 때문에, 이 크레이트들을 Rust 권고와 매칭할 수 없었습니다(Yocto 빌드 참고). 최신 Yocto 릴리스는 Cargo와 Go 소스에 생태계 purl을 추가합니다.
Package URL과 CPE 비교
| Package URL | CPE | |
|---|---|---|
| 이름을 정하는 주체 | 패키지의 생태계 | NVD의 CPE 사전 |
| 식별 대상 | 레지스트리나 배포판의 패키지 | 하드웨어와 운영체제를 포함한 제품 |
| 형식 | pkg:type/namespace/name@version | cpe:2.3:part:vendor:product:version:... |
| 표준 | ECMA-427 | NISTIR 7695(CPE 2.3) |
| 사용처 | OSV, GitHub 권고, SBOM 도구 | NVD, 많은 스캐너 |
| 흔한 실패 | 벤더링하거나 수동으로 기재한 코드에서 누락 | 모호한 공급업체·제품 이름, 많은 신규 CVE에 CPE 데이터 없음 |
기준은 이렇습니다. 생태계가 있는 모든 패키지에는 purl을 부여하고, 상용 소프트웨어, 펌웨어, 하드웨어처럼 생태계가 없는 것에는 CPE를 사용합니다. 식별자 불일치는 잘못된 탐지 결과의 주요 원인 중 하나입니다. 취약점 노이즈 줄이기를 참고하세요.
SBOM의 Package URL
CycloneDX와 SPDX는 모두 구성 요소마다 purl을 담습니다. CISA의 2026 Minimum Elements는 구성 요소 식별자에 "Common Platform Enumeration(CPE)과 Package-URL(PURL) 같은" 일반적인 식별자를 사용하라고 하며, 독일의 BSI TR-03183-2는 존재하는 경우 구성 요소마다 그런 식별자를 요구합니다. purl이 없는 것은 SBOM 완전성의 공백이라기보다 필드 품질의 문제입니다. 구성 요소는 기재되어 있지만 어떤 권고 데이터베이스도 이를 조회할 수 없습니다.
CRACI는 빌드가 가져오는 모든 패키지에 대해, Yocto 빌드의 Rust 크레이트 하나하나까지 Package URL을 기록하므로 SBOM을 보안 권고와 매칭할 수 있습니다. 빌드 시점 SBOM을 참고하세요.