There is a recent event where a Node.js developer decided to unpublish all of his 250 or so modules on npmjs.org (including some very popular modules, causing large breakage) following a corporate takedown notice for one of his modules. The ensuing HN discussion thread highlights a security issue where a malicious author could upload a malicious update to a previously existing (but then unpublished) module. I'm wondering how such issue is handled in the Perl (CPAN) community.

If someone unpublishes his module (i.e. deletes the release tarball from PAUSE), at least there's an extra step where he must also give up his primary maintainer/co-maintainer status to allow others to upload to the same package name. Well, that's not entirely correct. PAUSE allows any author to upload distribution which contains modules that occupy the same namespace as existing ones, it's just that the modules won't be indexed if the version number is older than existing indexed one or if there is insufficient permission. But once the original author makes the namespace available again, it's back to free for all: any other PAUSE author (malicious or not) can theoretically upload to the same namespace and spread malware or compromise users' systems via module update. It's easy to register a PAUSE account.

PAUSE creates a CHECKSUMS file in author's directory, listing each release file along with its last modified time, size, MD5 and SHA256 checksums. The CHECKSUMS file is then signed by PAUSE. A CPAN client can be instructed (e.g. --verify in cpanm) to check the signature of the CHECKSUMS file.

A couple of issues: 1) signature verification is not enabled by default in CPAN client (at least in cpanm); 2) most (all?) CPAN mirrors are ftp/http and not https, so during the first installation where the client does not have PAUSE's public key yet, a MITM attack can spoof the CHECKSUMS file as well as the release tarballs without the client being able to detect it. These issues can be fixed in the client: enable --verify by default and bundle the PAUSE public key.

Additionally, an author can also sign his distribution using a framework like Module::Signature. This will create a SIGNATURE file in the top-level directory of the distribution which contains the checksums of the files in the distribution. The SIGNATURE is then signed using the author's PGP key. This protects the distribution from being tampered by the server (in this case, PAUSE).

A CPAN client can then be instructed (also --verify in cpanm) to check this signature file. The 'cpansign' CLI tool distributed along with Module::Signature can also be used for this purpose. The same issue also exists: verify is not enabled by default. And another issue, code signing by author is not mandatory and as far as I know, only a small percentage of authors do this. And yet another issue, at least when I tried it, tool like 'cpansign' is not strict by default: when it fails to retrieve the required PGP public key, it stills reports "==> Signature verified OK! <=".

A more paranoid CPAN client can also be setup to only accept a predefined set of authors' keys. This can mitigate the issue of another previously unknown PAUSE author trying to push an update to existing module.

Client system can also protect against regular update breakage by setting up a private DarkPAN repository where each module update is first tested then pushed to this repository. Client machines then update their Perl modules from this private repository and not directly from a CPAN mirror.

Conclusion: there are mechanisms already in place in the CPAN infrastructure to prevent the abovementioned security issue. But the problem is they are not enabled by default.

  • Comment on What if someone liberated his Perl modules?

Replies are listed 'Best First'.
Re: What if someone liberated his Perl modules?
by Corion (Patriarch) on Mar 23, 2016 at 10:01 UTC

    In the somewhat longer history of CPAN, this has not happened, so I don't see any immediate cause for frantic action. I think most CPAN authors simply are more mature than the Node.js developer and won't cause havoc by removing a module used wide and far/with a long CPAN river downstream.

    A more paranoid CPAN client can also be setup to only accept a predefined set of authors' keys. This can mitigate the issue of another previously unknown PAUSE author trying to push an update to existing module.

    If you're using Perl and CPAN in a commercial setting, you do well by running your own, private CPAN and selectively importing modules into that private repository.

Re: What if someone liberated his Perl modules?
by Tanktalus (Canon) on Mar 25, 2016 at 20:17 UTC

    This is a secondary reason for what I'll do for production code: grab the CPAN tarball, and make it immutable in my build environment (whether that is check it in to version control or whatever). I don't have to worry about the upstream author breaking my code with an API change in a new version - I'll always use the old one. Until I'm ready to go through the upgrade/test cycle, where I do the upgrades on a single test machine, run the unit tests, and make any required changes to my code to compensate. The module are all installed from the immutable location exactly the way I need it, every single time.

    Sounds like npm doesn't really allow that to work? I'm not sure, my experience with npm is quite limited.

Re: What if someone deleted his Perl modules? (cpan/pause unauthorized)
by Anonymous Monk on Mar 23, 2016 at 09:13 UTC

    What if someone liberated his Perl modules?

    There is a recent event where a Node.js developer decided to unpublish all of his 250 or so modules on npmjs.org (including some very popular modules, causing large breakage) following a corporate takedown notice for one of his modules. The ensuing HN discussion thread highlights a security issue where a malicious author could upload a malicious update to a previously existing (but then unpublished) module. I'm wondering how such issue is handled in the Perl (CPAN) community.

    Calling deleting/removing your modules "liberation" is clownshoes; ok the guy called it that, but you're not that guy right? :P

    CPAN/PAUSE is first come first serve

    Once you register a namespace it is yours, even if you delete all releases, all other uploaders are "unauthorized"

    It takes human intervention to make someone elses upload "authorized"

    See http://pause.perl.org/pause/query?ACTION=pause_04about#takeover

    I didn't read the rest of your post

      Once you register a namespace it is yours, even if you delete all releases, all other uploaders are "unauthorized"

      It takes human intervention to make someone elses upload "authorized"

      That's why I wrote "an extra step of giving up primary/co-maintainer status".

        That's why I wrote "an extra step of giving up primary/co-maintainer status"..... once the original author makes the namespace available again, it's back to free for all: any other PAUSE author (malicious or not) can theoretically upload to the same namespace and spread malware or compromise users' systems via module update. It's easy to register a PAUSE account.

        IIRC (i'm not 100%) but it doesn't work like that, if you give up ownership, it still takes manual action by PAUSE administrators/moderators to grant somebody else ownership, unless you're giving it up to a co-maintainer, in which case ... you trusted the team once yeah, so :p