Skip to content

Exclude scripts from coherence check when publishing npm packages

🔭 Context

In the NPM package registry, when a package is uploaded, a background job will "process" it. At this time, different checks are executed.

One of them is called the manifest coherence check. In short words, when a NPM client uploads a package file, it sends:

  1. a tarball file (that's the file that is uploaded).
  2. a set of upload parameters (the upload payload).

The coherence check is there to make sure that (1.) and (2.) are coherent. Among the different fields, we check the scripts property.

The check is currently implemented as scripts in (1.) has to be the exact same than in (2.).

NPM clients (in particular, $ npm) does auto corrections on the package.json file content before sending it in the upload payload. The problem we discovered in gitlab-com/gl-infra/production#18253 (closed) is that in their usage, they will auto correct what is in (1.) to build (2.).

For example, when $ npm inspects scripts, it will remove any ./node_modules/.bin/ suffix from any script. So, in the tarball's package.json, the scripts can be like:

{
  ...
  "scripts" : { "foo:bar" : "./node_modules/.bin/bar arg1 arg2" }
  ...
}

And what will be sent in the upload request payload will be autocorrected to be like:

{
  ...
  "scripts" : { "foo:bar" : "bar arg1 arg2" }
  ...
}

Now, what happens with our coherence check? (./node_modules/.bin/bar arg1 arg2 vs bar arg1 arg2) Yes, 💥

Based on that above, we checked with the Application Security Team if we can exclude the scripts property from the coherence check, and we received their approval.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After

How to set up and validate locally

  1. Get a project and a PAT ready.
  • Create a folder with:

    1. package.json :

      {
        "name": "@scope/test",
        "version": "5.0.5",
        "scripts" : {
          "start": "./node_modules/.bin/jest --config ./jest.config.json"
        },
        "main": "index.js"
      }
    2. .npmrc (replace <pat> and <project_id>):

    @scope:registry=http://gdk.test:8000/api/v4/projects/<project_id>/packages/npm/
    //gdk.test:8000/api/v4/projects/<project_id>/packages/npm/:_authToken="<PAT>"
  • run $ npm publish

  • The package is successfully published.

  • On master Package manifest is not coherent error

Related to #472630 (closed)

Edited by Moaz Khalifa

Merge request reports

Loading