Runtime Module Hooks
envtrap injects a runtime hook script (hooks.mjs) into the application process via NODE_OPTIONS="--import hooks.mjs".
This script executes before any user code or dependencies are loaded, establishing hooks for both ECMAScript Modules (ESM) and CommonJS (CJS).
1. ES Modules (module.register)
Node.js 18+ provides module customization hooks that intercept module resolution and loading:
Module Resolution (resolve hook)
Module Resolution (resolve hook)
When application code or an npm package imports
node:child_process or node:dns, the resolve() hook intercepts the specifier and redirects it to an internal virtual URL protocol:Module Loading (load hook)
Module Loading (load hook)
When Node.js attempts to load an
envtrap:* URL, the load() hook serves our specialized virtual wrapper module (src/hooks/virtual/child-process.mjs or src/hooks/virtual/dns.mjs) directly from memory:2. CommonJS (Module.prototype.require)
Because older packages still use CommonJS require(), hooks.mjs patches Module.prototype.require in the main application thread:
import statements and CommonJS require() calls receive identical security enforcement.
3. Call-Stack Path Exclusions
Before triggering an alert or throwing an error, virtual hooks inspect the execution call stack:- An
Errorobject is instantiated to capture the active call stack. - The calling file path is evaluated against glob patterns configured in
exclusions.paths. - If the calling file is excluded (such as test suites or database seeders), the operation is permitted without raising an alert.
