Dangerous Process-Hijacking Environment Variable Injected via Config/Env-Update Tool
An attacker who only has access to an application's configuration or environment settings API — not its source code — can still get code execution. They do this by setting a well-known runtime environment variable that makes a program load an attacker-controlled file the next time it starts.
How the attack works
The attacker calls a config or environment-update endpoint or tool that is supposed to let users set application settings like PORT or LOG_LEVEL. Instead, they set one of a small set of dangerous variables — NODE_OPTIONS, LD_PRELOAD, DYLD_INSERT_LIBRARIES, PYTHONSTARTUP, BASH_ENV, PERL5OPT, RUBYOPT, or GCONV_PATH — to a path pointing at a file they control, or to a flag that changes runtime behavior. These variables are recognized by Node.js, Python, Bash, Perl, Ruby, or the dynamic linker itself, and cause the runtime to load or execute the attacker's file automatically. The payload doesn't run immediately; it runs the next time the affected process or a new instance of it starts, which can be triggered by a restart, redeploy, or crash-recovery. This was documented in anything-llm's environment-update API (CVE-2024-3104), which accepted any variable name or value with no allowlist.
Netzilo detection
Netzilo reports this behaviour when it is observed.
- Signature ID
- ce37ea44-17e9-4c9f-91a7-fdc09ad9dcc4
- Severity
- Critical
- CVEs
- CVE-2024-3104
Why it matters
An attacker with only config-level or environment-variable-level access — often a lower privilege than code deployment — can escalate to full arbitrary code execution on the host running the application the next time it restarts.
What you can do
- →Put an allowlist on any endpoint or tool that sets environment variables, rejecting known process-hijacking variable names outright.
- →Reject environment variable values that look like file paths, flags, or shared-library references unless explicitly reviewed.
- →Audit existing environment-update or config-update endpoints for missing input validation, especially in AI agent tooling that exposes system configuration as a callable tool.
- →Restart your services in a locked-down environment (container, minimal filesystem) so that even a hijacked runtime has little to load or execute.
Known benign look-alikes
- A DevOps runbook or documentation discussing these variable names in prose without an accompanying config/env-update tool-call context
- A legitimate, security-reviewed deployment script that intentionally sets LD_PRELOAD/NODE_OPTIONS for approved instrumentation (e.g. an APM agent) via a config/update-env style call -- rare but possible; still worth a human check given the severity of process-hijacking if the value turns out to be attacker-controlled
- Shell-syntax examples in security-education content (e.g. 'sudo LD_PRELOAD=/tmp/shell.so find') that show the variable being set directly in a shell, without any update-env/setenv/config-API framing
- Routine NODE_OPTIONS flags that are not a require/loader mechanism -- 'NODE_OPTIONS=--max-old-space-size=4096', 'NODE_OPTIONS=--inspect=9229', 'NODE_OPTIONS=--no-warnings', '--stack-size=...' -- these tune memory/debugging/warnings and carry no code-loading capability, so they must not fire