Two Perl distributions on CPAN โ Crypt::SelfCertificate and IO::Socket::SSL::SelfCertificate โ have been carrying embedded malicious code, tracked as CVE-2026-95831 and CVE-2026-97230. Both modules exist to help developers generate self-signed TLS certificates for local testing, a task that gets pulled into CI pipelines, dev containers, and internal tooling without much scrutiny. Instead of a certificate, the payload they generate is a dropper.
What happened
Researcher robrwo flagged the packages to briandfoy/cpan-security-advisory (tracked publicly as issue #437), and the CPAN Security Advisory database published both entries around September 22-24, 2026. Crypt::SelfCertificate versions 1.01 through 1.05 and IO::Socket::SSL::SelfCertificate version 1.00 are affected. Both distributions ship a generate_certificate function that has been altered from its advertised behavior โ instead of only writing out a PEM certificate, it also loads and processes a file at lib/Crypt/SelfCertificate/sample/cert.pem.
That file isn’t a certificate. It’s Python source, base64-obfuscated and disguised with PEM-style header/footer lines so it passes a casual glance as certificate material. When generate_certificate is invoked โ which happens the first time an application actually uses the module for its stated purpose โ the embedded Python is decoded and handed to a python interpreter, which then reaches out to a hardcoded HTTP URL, retrieves a second-stage payload, and executes the response body directly in memory. No file is ever written to disk for the final payload, which defeats file-hash and static-signature detection.
Why it evaded review
Both packages skip the usual signals reviewers rely on to sanity-check obscure dependencies:
- No test suite. Neither distribution ships meaningful
t/test scripts, which also means CPAN Testers’ automated smoke-test network never exercisedgenerate_certificatein a way that would have surfaced the outbound HTTP call. - No build/install hooks. The malicious path only fires on legitimate use of the module’s core function, not at
cpanm/cpan installtime โ so install-time monitoring tuned to catchMakefile.PL/Build.PLorBEGIN-block abuse (the pattern npm scanners chase forpreinstallscripts) doesn’t trigger here at all. - Plausible file naming. A
sample/cert.pemsitting next to certificate-generation code looks exactly like what you’d expect to find in that kind of module, which is precisely why it wasn’t flagged sooner.
The CPAN Security Advisory maintainers describe the absence of tests and hooks as consistent with deliberate evasion rather than accidental breakage โ this reads as a module written specifically to carry the payload, not a legitimate tool that was later compromised.
Impact
Any application, script, or CI job that calls generate_certificate() from either affected distribution executes attacker-controlled code with the privileges of the process running it โ which in CI/CD and container-build contexts routinely includes registry credentials, cloud API keys, and source-control tokens. Because the fetch-and-exec happens in memory with no persistent artifact, standard EDR file-scanning and CPAN-mirror integrity checks are unlikely to catch it after the fact; detection depends on outbound-connection monitoring or process-behavior telemetry that flags a Perl process spawning a python interpreter that immediately opens an outbound HTTP connection.
This is a narrower blast radius than an npm-style worm โ neither Crypt::SelfCertificate nor IO::Socket::SSL::SelfCertificate has meaningful download volume compared to core CPAN distributions โ but it’s a reminder that the CPAN ecosystem, despite far less tooling investment than npm/PyPI in automated malware scanning, is an equally viable delivery vector, especially into legacy Perl-based infrastructure (cPanel/WHM stacks, network gear management scripts, and internal automation) that rarely gets the same dependency-audit attention as JS/Python projects.
Mitigation
- Audit dependency trees (
cpanfile,cpanm --showdeps,MYMETA.json) forCrypt::SelfCertificate1.01-1.05 andIO::Socket::SSL::SelfCertificate1.00. - Remove or pin to a version predating the malicious releases; both advisories are marked fixed in the current CPAN Security Advisory database (release
CPANSA-DB-20260923.001), so re-resolving to a patched/clean release is sufficient once your mirror has synced. - If either module executed in a CI runner, build container, or production host, rotate any credentials available to that process (cloud keys, registry tokens, SSH/GPG material) and inspect egress logs for connections to unexpected HTTP endpoints around the time
generate_certificatewould have run. - For any local self-signed-cert tooling going forward, prefer well-maintained, widely-audited alternatives (
Net::SSLeay, OpenSSL CLI wrappers) over single-maintainer convenience modules pulled in for one-off dev tasks. - Neither CVE is currently listed in the CISA KEV catalog, and no in-the-wild exploitation beyond the malicious releases themselves has been reported โ this is a supply-chain compromise at the source, not a remotely triggered vulnerability in otherwise-legitimate code.
Advisory: briandfoy/cpan-security-advisory issue #437 ยท CPANSA-DB-20260923.001 release