lote.guide
esc
  • npm lifecycle scriptsscripts field in package.jsonNode.js
  • setup.py arbitrary code executionsetup.py in source distributions (sdist)Python
  • NODE_OPTIONS preload injectionNODE_OPTIONS environment variable, CLI flags, or .env files loaded via --env-fileNode.js
  • .pth file import execution*.pth files on sys.path (commonly site-packages)Python
  • binding.gyp / node-gyp native compilationbinding.gyp file in the package rootNode.js
  • Corepack (packageManager field)"packageManager" field in package.json, COREPACK_HOME cache directoryNode.js
  • .npmrc registry manipulation.npmrc file (project, user, or global)Node.js
  • overrides / resolutions dependency swapoverrides (npm) or resolutions (Yarn) field in package.jsonNode.js
  • pnpm hooks (pnpmfile.cjs).pnpmfile.cjs in the project rootNode.js
  • .yarnrc.yml plugins and registry.yarnrc.yml in the project rootNode.js
  • pyproject.toml build backendspyproject.toml [build-system] tablePython
  • sitecustomize / usercustomize auto-importsitecustomize.py / usercustomize.py on sys.path (usually site-packages)Python
  • .node native addon loading.node files in node_modules/ (typically under build/Release/ or prebuilds/)Node.js
  • Yarn Plug'n'Play (.pnp.cjs).pnp.cjs in the project rootNode.js
  • __init__.py execution on import__init__.py in any package directory on sys.pathPython
  • .pyc bytecode cache poisoning.pyc files in __pycache__/ directories alongside source modulesPython
  • PYTHONPATH / PYTHONHOME module shadowingPYTHONPATH / PYTHONHOME environment variablesPython
  • npx / npm exec remote executionnpx, npm exec, npm create / npm init (initializer flows)Node.js
  • conftest.py auto-loading (pytest)conftest.py files in any directory pytest traversesPython
  • NODE_PATH environment variableNODE_PATH environment variableNode.js
  • "imports" field (subpath imports)imports field in package.jsonNode.js
  • require.extensions / Module._extensionsrequire.extensions / Module._extensions in any loaded moduleNode.js
  • .egg files and EGG-INFO scripts.egg files in site-packages (registered via easy-install.pth)Python
  • Zip imports (zipimport).zip / .pyz files on sys.path, or passed directly to the interpreterPython
  • PYTHONSTARTUP environment variablePYTHONSTARTUP environment variablePython
  • node_modules/.hooks/ directorynode_modules/.hooks/ directoryNode.js
Node.js
Module resolution/File on disk

.node native addon loading

On require() of the .node file, via process.dlopen()

Lives in
.node files in node_modules/ (typically under build/Release/ or prebuilds/)
Attacker needs
Filesystem write access, Supply-chain foothold
Lifecycle
Install
Startup
your code
Module load
Runtime
REPL

Runs on import or require, for every module the app loads.

How it runs

binding.gyp runs code at compile time. This runs it at load time. When require() encounters a .node file, Node calls process.dlopen(), which maps directly to the system's dlopen(). Arbitrary native code then executes with the full permissions of the Node process. There's no sandbox and no JS-level permission check.

const addon = require('./build/Release/addon.node'); // runs native init immediately

A .node file is a shared library (.so / .dylib / .dll). Its initialization function runs the moment it loads, and it can do anything a C program can. The attack is substitution. If an attacker can replace a .node in node_modules/ through a compromised package, a writable directory or a swapped prebuilt binary, the malicious native code executes on the next require().

Unlike JavaScript, .node binaries are opaque to code review and static analysis. You can't grep a shared library for curl https://evil.com, and most scanners skip binaries. Packages that ship prebuilt binaries download .node files from URLs in package.json. If that URL is compromised or served over HTTP, the binary could be anything.

Defend

Verify integrity of prebuilt binaries; download over HTTPS with checksums; restrict write access to node_modules; monitor for binary substitution.