npm Blog (Archive)

The npm blog has been discontinued.

Updates from the npm team are now published on the GitHub Blog and the GitHub Changelog.

CouchDB vulnerabilities and the npm registry

Recently a serious vulnerability in Apache CouchDB was discovered, patched, and disclosed. In this post we discuss its impact on the npm registry and correct some incorrect speculation on that impact.

The npm package registry is a well-known deployment of Apache CouchDB and we occasionally sing its praises in public. (To recap: it’s wonderfully easy operationally, and its replication features are its superpower.) Recently, two security vulnerabilities were found and patched in Couch. You can read the details in their blog post: Apache CouchDB CVE-2017-12635 and CVE-2017-12636. The CouchDB project very kindly let us know that we would want to patch our public-facing services on their next software release. They did not disclose to us the details of the vulnerability, but advised us it was serious. We followed our usual operational procedures and updated.

The person who discovered one of the vulnerabilities patched, Max Justicz, has written their own blog post on the topic: Remote Code Execution in CouchDB (and Privilege Escalation in the npm Registry). They raise some questions in this blog post about how npm might have been affected by this vulnerability. In particular I’d like to address this speculation:

I am almost certain that registry.npmjs.org was vulnerable to the privilege escalation/admin account creation part of this attack, which would have allowed an attacker to modify packages. This is because user creation on npm is more or less identical to the vanilla CouchDB user creation flow.

This speculation, while reasonable, is incorrect. Neither the public npm registry nor npm Enterprise installations are vulnerable to this bug because they do not use the CouchDB user system. The API presented is identical to CouchDB for compatibility with older versions of the npm client, but it is implemented via a proxy service that intercepts requests, rewrites them, and forwards them to another microservice. npm’s user and access control data is stored in postgresdb. This has been true since early 2015.

There were two services that were vulnerable to the bug until patched, however, as speculated in the blog post: our two public replication services. skimdb.npmjs.com is our legacy replication service, which provides a CouchDB changes feed for all unscoped packages in the registry. replicate.npmjs.com is a replication service for all public packages in the registry, including scoped packages. (These are packages with names like @slack/client or @std/esm.) We patched those CouchDB instances last week when the fix for this vulnerability landed.

We do not allow publication to these two CouchDB instances, so a breach would not have affected data in the npm registry. (Package data is downstreamed into these services through means decoupled from main registry operations.)

We deeply appreciate the responsible disclosure and cooperative spirit displayed by Max Justicz, who also made sure we were patched in advance of making his blog post. If you are aware of a package vulnerability or a vulnerability in any of npm’s system, please do contact us via email: security@npmjs.com.