Crypt::SelfCertificate hides executable code in certificate samples
CPANSec has identified malware in Crypt::SelfCertificate and assigned CVE-2026-95831. Its initial report points to Python code stored under certificate filenames and asks CPAN Testers to investigate potentially affected systems.
CPANSec has reported malware in Crypt::SelfCertificate today, September 22, and assigned CVE-2026-95831. The initial message identifies malicious versions beginning with 1.01 and describes a certificate-generation path that invokes Python code stored in a sample file. It also asks CPAN Testers who downloaded and tested the distribution to investigate their systems.
The CPANSec CVE record, published today, identifies versions 1.01 through 1.05. Its description says the Python script retrieves code through an obfuscated hardcoded HTTP URL and runs the response body. The relevant evidence is executable behavior inside a package presented as certificate tooling. A filename that looks like certificate data does not explain what the file contains or how the module uses it.
I have used Perl for nearly thirty years and still value CPAN as part of the language. That history makes this a dependency incident I want to understand precisely. The response needs to preserve the distinction between what CPANSec has established about the package and what an investigation has established about a particular host. The first report explicitly says analysis is continuing.
The sample file participates in execution
The initial advisory identifies lib/Crypt/SelfCertificate/sample/validate.p12 in 1.01 and lib/Crypt/SelfCertificate/sample/cert7.pem in 1.05. Those paths look like certificate-related samples. CPANSec identifies them as locations of the dropper script. The CVE description explains that the certificate-generation operation runs that script with Python.
The extension and directory provide weak evidence about a file role. The consuming code determines whether a file is parsed as data or passed to an interpreter. For this package, the relevant relationship is the call that turns the sample into executable input. Listing the archive contents without following that relationship would leave the mechanism unexplained.
The report supplies hashes for the affected archives and sample files. Those identifiers let investigators compare retained artifacts without executing them. A comparison result needs the original advisory so that the digest remains associated with the correct archive or internal file. A match to a sample-file digest and a match to an archive digest establish different things.
Package inventories and retained download records provide a starting point for triage. For an affected archive, the record needs its origin and the process that handled it. Finding the package establishes a reason to investigate. It does not by itself establish when the malicious function ran or what a remote server returned at that time.
Running the package on an ordinary development host would create another potential exposure. The published mechanism already explains why that can execute remotely retrieved code. A reproduction that creates another execution is not necessary to identify an installed distribution or compare an artifact digest. Any further dynamic analysis needs an environment designed for that investigation.
Installation and later use are different questions
The initial message notes that the distributions have no test scripts and suggests that the intended trigger may be after installation. CPANSec still asks testers to check systems where they downloaded and ran tests. That combination deserves careful reading. Absence of a distribution test suite is not an assertion that every machine involved in processing the package is unaffected.
The CVE description also says the releases have no build hooks. That narrows the reported mechanism, but it does not turn installation records into proof of safety. Investigators need to establish what actually ran in their environment. A package can be installed and later invoked through a different operation, and those events may have separate records.
A test service needs to establish whether its work included only building the distribution or also exercising the installed module. The answer should come from its configuration and execution records. The label CPAN Tester alone does not describe a complete workflow. Different environments can have different permissions and available inputs even when they report results to the same community service.
For an application host, the investigation needs to establish whether it calls the certificate-generation operation described in the report. That is a reachability question about this program. It helps establish exposure, while the installed package remains evidence worth retaining for investigation. A search that finds no direct call in one source tree may miss another tool or scheduled operation using the same installation.
The incident record also needs the execution identity. CPANSec describes arbitrary code running as the user. The permissions and credentials available to that process determine what an investigator needs to examine. A package-name match does not answer those questions, and an advisory cannot know the local account context of every installation.
Removal limits distribution but does not resolve a host incident
The first report says PAUSE has been notified and that removal from CPAN and BackPAN is expected shortly. As of this report, that is a requested containment step. Completed removal requires a separate observation. The distinction matters when an incident is still developing.
Archive removal and host recovery also have different effects. Removing a distribution from an upstream service reduces another route to obtaining it. It does not establish that an already downloaded copy has disappeared or that code already executed on a host has left no effects. A response needs to assess the systems that handled the package independently of the upstream removal request.
The CVE record advises treating systems with the affected package installed as potentially compromised and investigating them accordingly. That cautious status needs to remain until host evidence supports a narrower conclusion. It is more specific than claiming every installation has suffered a confirmed compromise, and it avoids declaring a system clean merely because the package has been uninstalled.
If a host has potentially executed the payload, preserving available evidence needs to precede rebuilding it. The investigation should account for the process identity and accessible credentials, with recovery decisions based on that scope. Removing the original module cannot establish what remotely retrieved code did after it ran. CPANSec has not claimed to know every downstream effect in the initial disclosure.
Test infrastructure needs a separate exposure record
The request to CPAN Testers makes shared test infrastructure part of the response. The exposure record needs the exact distribution and version processed by each worker, along with the execution environment. An aggregate successful test result is not a security assessment of everything a package can do. The immediate question is what that worker executed and what it could access.
This is also a reason to distinguish dependency testing from dependency approval. A package can satisfy functional expectations while containing another execution path. Tests selected for ordinary behavior may never reach that path. The advisory identifies a need for additional evidence beyond passing functional tests.
Retained caches also need review alongside active installations. A cached archive can be relevant to identifying which package a past worker used, even after a clean rebuild removes its installed files. Preserving that association helps another investigator reproduce the inventory conclusion without rerunning the package. The useful record connects the artifact to the machine and handling event.
A response should also describe uncertainty explicitly. Missing execution records limit what download records alone can establish. If the certificate-generation call is confirmed, the record should say so separately. Combining those states under a single affected label makes it harder to decide what recovery evidence is still missing.
Upstream package identity needs to remain distinguishable from any locally renamed copy. A local filename can change while the archive bytes remain identical, and an unpacked directory can outlive its original archive. The published digests support comparison against retained files, while installation logs explain how those files entered an environment. Neither kind of evidence should silently substitute for the other. When one is unavailable, the investigation should record the missing association and the resulting limit on its conclusion.
The distinction between an archive and its contents also affects evidence retention. A digest of the downloaded archive identifies that compressed artifact. A digest of an internal sample identifies that file even when it appears in a different archive. Both comparisons need their own recorded target and result.
My immediate judgment is to suspend use of the affected distribution and follow CPANSec updates through the linked report. The immediate review would retain the installed version and artifact identity, then establish whether the reported execution path ran. Any conclusion about the host would state what was observed and what could not be recovered from the available records.