Make WordPress Core

Opened 4 months ago

Last modified 4 days ago

#64543 new task (blessed)

Implement `ignore-scripts` to harden npm usage

Reported by: johnbillion's profile johnbillion Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Build/Test Tools Keywords:
Focuses: javascript Cc:

Description

Lifecycle scripts in npm packages -- in particular postInstall scripts -- are a significant security concern because by default they execute automatically for all dependencies.

Running npm install or npm ci not only installs packages but also runs the postInstall script in every direct and transitive dependency in the entire dependency tree. The recent "Shai-Hulud" supply chain attack on the npm ecosystem has been successful in part due to postInstall scripts that have allowed it to rapidly self-propagate.

We should strongly consider implementing ignore-scripts = true in the .npmrc file in order to disable the automatic execution of lifecycle scripts. This will primarily help protect contributors against malicious postInstall scripts that may be introduced by attacks on packages in the dependency tree.

Ironically WordPress core just introduced its own postInstall script in #64393. This is far from ideal.

Making this change will cause some short-term pain while we determine the best way to ensure that all dependencies continue to work and/or provide clear instructions for contributors if manual subsequent steps become necessary. As the ecosystem reels from "Shai-Hulud" supply chain attack I fully expect to see more packages remove their postInstall scripts in favour of documenting subsequent steps necessary to, for example, install dependent binaries.

There's some tooling available to assist with determining which dependencies include lifecycle scripts, but not a lot:

Related links:

Change History (4)

#2 @jonsurrell
4 months ago

  • Focuses javascript added

#3 @desrosj
4 days ago

In 62321:

Build/Test Tools: Remove gutenberg:verify script on postinstall.

In [61458], a postinstall script was introduced that ensured the source code from the gutenberg repository was present before attempting to run the build script.

The WordPress.org Hosting Tests surfaced an edge case where the postinstall script was failing when nodevenv is used. Because it serves as a wrapper for Node.js, NPM_CONFIG_PREFIX is set to the virual envirnoment directory and not the actual project source directory.

This removes gutenberg:verify from postinstall entirely. gutenberg:verify is responsible for confirming that the gutenberg directory exists, that the commit SHA value in gutenberg/.gutenberg-hash matches gutenberg.sha in the package.json file, and it downloads a fresh copy if not.

While this will result in the necessary files not being present locally after running npm install, gutenberg:verify is specified as the first task executed when the build and build:dev scripts are run. Running either build script has been a requirement to run WordPress locally for some time now, so this does not introduce a new required step. It simply delays when the built asset will be retrieved from the GitHub Container Registry when necessary.

postinstall scripts should also be avoided entirely due to their significantly insecure nature (see #64543).

Follow up to [61492], [61873], and [62021].

Props jorbin, johnbillion.
Fixes #64874. See #64393, #64543.

#4 @desrosj
4 days ago

In 62330:

Build/Test Tools: Remove gutenberg:verify script on postinstall.

In [61458], a postinstall script was introduced that ensured the source code from the gutenberg repository was present before attempting to run the build script.

The WordPress.org Hosting Tests surfaced an edge case where the postinstall script was failing when nodevenv is used. Because it serves as a wrapper for Node.js, NPM_CONFIG_PREFIX is set to the virual envirnoment directory and not the actual project source directory.

This removes gutenberg:verify from postinstall entirely. gutenberg:verify is responsible for confirming that the gutenberg directory exists, that the commit SHA value in gutenberg/.gutenberg-hash matches gutenberg.sha in the package.json file, and it downloads a fresh copy if not.

While this will result in the necessary files not being present locally after running npm install, gutenberg:verify is specified as the first task executed when the build and build:dev scripts are run. Running either build script has been a requirement to run WordPress locally for some time now, so this does not introduce a new required step. It simply delays when the built asset will be retrieved from the GitHub Container Registry when necessary.

postinstall scripts should also be avoided entirely due to their significantly insecure nature (see #64543).

Follow up to [61492], [61873], and [62021].

Reviewed by jorbin.
Merges [62321] to the 7.0.

Props jorbin, johnbillion, desrosj.
Fixes #64874. See #64393, #64543.

Note: See TracTickets for help on using tickets.