Perl
Package analysis
| Cataloger + Evidence | Package URL Type | License | Dependencies | Package Manager Claims | ||||
|---|---|---|---|---|---|---|---|---|
| Depth | Edges | Kinds | Files | Digests | Integrity Hash | |||
perl-cpan-installed-cataloger auto/**/.packlist | pkg:cpan | |||||||
perl-cpan-installed-cataloger .meta/*/install.json | pkg:cpan | Transitive | Complete | Runtime, Build | ||||
perl-cpan-meta-cataloger META.json, META.yml | pkg:cpan | |||||||
Perl packages are cataloged as CPAN distributions, not as modules.
A distribution is the unit that CPAN, MetaCPAN, and CPAN’s advisory data all use, so you see libwww-perl rather than LWP, and URI rather than URI::Escape.
Every cataloged package has type cpan and a purl of the form pkg:cpan/<distribution>@<version>.
When the evidence carries the PAUSE author id it is added as an author qualifier, for example pkg:cpan/URI@5.35?author=OALDERS.
What is and is not cataloged
Only distribution-level identity is emitted, and three kinds of evidence are read to produce it:
install.jsonunder a.metadirectory, written bycpanm,cpm, andcarton.packlist, paired withperllocal.podfor the version, falling back to scraping$VERSIONfrom the main.pmwhenperllocal.podis absent- an unpacked release’s own
META.jsonorMETA.yml, alongside a siblingMANIFEST
Module-level evidence is read where it exists (install.json records a provides map with per-module versions), but it is used to resolve dependency edges rather than reported as packages of its own.
Both meta file names are read because roughly 43% of current CPAN releases ship no META.json at all.
The sibling MANIFEST is what gates the unpacked-release case: a built release tarball ships one, a source checkout does not, and without that check every project with a committed meta file would be reported as an installed distribution.
The coverage boundary follows from that:
- CPAN client installs are cataloged, wherever they live, including local-lib trees such as an application’s
local/lib/perl5.cpanm,cpm, andcartonwriteinstall.jsononly when the distribution was resolved from a mirror, so a local directory or tarball install (cpanm .,cpanm ./Foo-1.0.tar.gz) writes none, andCPAN.pmnever writes one. Those installs are picked up by the packlist pass instead. This is why the officialperl:5.40-slimimage has no.metadirectories at all and every Perl package reported from it comes from a packlist. - A
.packlistis written by theExtUtils::MakeMakerandModule::Buildinstall targets, unless it is suppressed withNO_PACKLIST, which is what distro packagers set. - A packlist-derived name is the installer’s
NAME, which is usually but not always the distribution name.libwww-perlinstalls toauto/LWP/.packlist, so that is the name you see. Resolving those to distributions is left to the vulnerability data, which carries the mapping. - Perl modules installed from distro packages are not cataloged here. They carry no CPAN-native metadata, because packagers suppress it, and they are already reported by the deb, rpm, and apk catalogers. Reporting them twice would be worse than not reporting them here. So
libwww-perlfrom apt stays adebpackage,perl-URIfrom dnf stays anrpmpackage, andperl-urifrom apk stays anapkpackage. - Core and dual-life distributions bundled with the interpreter are not cataloged. Nothing on disk carries their versions, so there is nothing to read. This is a real gap: 26 of the distributions that carry advisories are dual-life in perl 5.40, including
Encode,Storable,HTTP-Tiny, andArchive-Tar. The interpreter itself is reported separately and advisories against theperldistribution do get matched, so the gap is the distributions bundled inside it rather than perl itself. Installing a newer copy of one from CPAN makes that copy visible. - Build leftovers under
~/.cpanm/workand~/.cpan/buildare skipped. They are unpacked release tarballs,MANIFESTincluded, but they describe a copy that is already installed elsewhere on the same image. - Vendored
.pmtrees, App::FatPacker output, and PAR archives are invisible. What they carry is module identity, and there is no offline map from a module to the distribution that shipped it. Fatpacked output does embed the.pmsources verbatim,$VERSIONlines included, so the missing fact is the distribution rather than the version. - A
cpanfileorcpanfile.snapshotis not parsed yet. A snapshot is a resolved lockfile, and in a source checkout or CI workspace, wherelocal/does not exist, it is the only evidence there is. This is deferred rather than out of scope.
The perl interpreter
The perl interpreter binary is reported as pkg:cpan/perl@<version>, not pkg:generic/perl@<version>.
perl is itself a CPAN distribution and carries advisories under that name, so typing it as cpan is what makes those advisories reachable.
Note
This changes an existing purl. Allowlists, policies, and SBOM comparisons keyed onpkg:generic/perl need to be updated to pkg:cpan/perl.Vulnerability scanning
| Data Source | Disclosures | Fixes | Track by Source Package | ||
|---|---|---|---|---|---|
| Affected | Date | Versions | Date | ||
| National Vulnerability Database (NVD) | |||||
| Configuration Key | Description |
|---|---|
match.stock.using-cpes | Use CPE package identifiers to find vulnerabilities |
Version comparison
Perl versions are compared using perl’s own version.pm semantics rather than semver, because the two disagree on the most common version shape on CPAN.
Under perl’s rules a decimal version is a fraction, so 1.2 is greater than 1.10, and 1.23 is greater than 1.2.3.
Perl also treats a packed decimal and a dotted version as equal, so 5.008001 and 5.8.1 are the same version.
Advisory coverage
Perl advisory data comes from CPANSA, the CPAN Security Advisory database.
CPANSA is keyed on distribution names, which is the same key Syft reports, so libwww-perl is the name that carries advisories and LWP is not.