Skip to content

fix(security): block JVM, Python, and .NET env injection vectors in host exec sandbox#49025

Merged
ademczuk merged 2 commits intoopenclaw:mainfrom
ademczuk:fix/security-env-blocklist
Mar 17, 2026
Merged

fix(security): block JVM, Python, and .NET env injection vectors in host exec sandbox#49025
ademczuk merged 2 commits intoopenclaw:mainfrom
ademczuk:fix/security-env-blocklist

Conversation

@ademczuk
Copy link
Copy Markdown
Contributor

@ademczuk ademczuk commented Mar 17, 2026

Closes #22681

JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, and JDK_JAVA_OPTIONS let an attacker inject -javaagent into any JVM process spawned by an agent. PYTHONBREAKPOINT can redirect Python's breakpoint() to an arbitrary callable like os.system. DOTNET_STARTUP_HOOKS loads arbitrary assemblies into .NET hosts before Main() runs. None of these have legitimate use inside the exec sandbox.

This adds all five vars to blockedKeys in host-env-security-policy.json and regenerates the Swift policy file. Strictly additive - no existing entries removed or moved.

Changes

  • src/infra/host-env-security-policy.json: add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, DOTNET_STARTUP_HOOKS to blockedKeys
  • apps/macos/Sources/OpenClaw/HostEnvSecurityPolicy.generated.swift: regenerated via scripts/generate-host-env-security-policy-swift.mjs
  • src/infra/host-env-security.test.ts: assertions for all new entries including case-insensitive match

Why these specific vars?

Variable Attack vector Runtime
JAVA_TOOL_OPTIONS Inject -javaagent:/path/evil.jar on any JVM startup (JVMTI standard) JVM
_JAVA_OPTIONS Same injection path, non-standard but supported by HotSpot/OpenJDK JVM
JDK_JAVA_OPTIONS Java 9+ standardized replacement JVM
PYTHONBREAKPOINT Redirects breakpoint() to arbitrary callable (e.g. os.system) Python 3.7+
DOTNET_STARTUP_HOOKS Loads arbitrary assemblies and runs StartupHook.Initialize() before Main() .NET Core 3.0+

Not included (already covered or not dangerous)

  • LD_PRELOAD, LD_LIBRARY_PATH, LD_AUDIT caught by existing LD_ prefix block
  • DYLD_INSERT_LIBRARIES caught by DYLD_ prefix block
  • PYTHONPATH and PYTHONHOME already in blockedKeys
  • PYTHONEXECUTABLE excluded after verification - it only affects sys.argv[0] reporting on macOS, no execution control

Prior art

#45174 by @BenediktSchackenberg covers some of the same JVM vars but bundles them with unrelated changes to blockedOverrideKeys (removes GIT_SSH, OPENSSL_CONF, HISTFILE, etc.). This PR is a focused subset that avoids those scope issues.

Test plan

  • pnpm test -- src/infra/host-env-security.test.ts passes (11 tests)
  • pnpm test -- src/agents/bash-tools.exec-runtime.test passes (3 tests)
  • pnpm check clean
  • CI green

@openclaw-barnacle openclaw-barnacle bot added app: macos App: macos size: XS maintainer Maintainer-authored PR labels Mar 17, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 17, 2026

Greptile Summary

This PR makes a well-scoped, strictly additive security improvement by blocking five env-injection vectors (JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, DOTNET_STARTUP_HOOKS) from the host exec sandbox. The implementation is consistent across the JSON policy file and the regenerated Swift file, and the tests now correctly cover all five new entries with both uppercase and lowercase assertions.

Key observations:

  • All 5 new blockedKeys entries are correctly mirrored in HostEnvSecurityPolicy.generated.swift — no drift between sources.
  • Test coverage is thorough: each new variable is tested case-insensitively, fully addressing the gap noted in the previous review thread.
  • One gap worth noting: DOTNET_STARTUP_HOOKS (managed code) is now blocked, but the .NET CLR profiler API (CORECLR_ENABLE_PROFILING, CORECLR_PROFILER, CORECLR_PROFILER_PATH) provides a native-code injection path into .NET processes that is not covered by the existing LD_ prefix block and is absent from blockedKeys. This is outside the stated scope of this PR but worth a follow-up.

Confidence Score: 5/5

  • This PR is safe to merge — changes are strictly additive, correctly implemented, and well tested.
  • All five new blockedKeys entries are consistent between the JSON policy and the generated Swift file. Tests cover all new entries with case-insensitive variants. No existing entries are removed or modified. The only observation is a missing CORECLR_* trio for full .NET native profiler coverage, which is outside this PR's stated scope and appropriate for a follow-up.
  • No files require special attention.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/infra/host-env-security-policy.json
Line: 25

Comment:
**Missing .NET CLR profiler injection trio**

`DOTNET_STARTUP_HOOKS` is now blocked (managed code injection), but the CLR profiler API is a parallel native-code injection vector that isn't caught by the existing `LD_` prefix block:

| Variable | Role |
|---|---|
| `CORECLR_ENABLE_PROFILING` | Activates the profiler (`1` enables it) |
| `CORECLR_PROFILER` | CLSID of the profiler COM object |
| `CORECLR_PROFILER_PATH` / `CORECLR_PROFILER_PATH_64` | Path to the native profiler `.so`/`.dll` loaded before `Main()` |

Setting all three causes the .NET runtime to `dlopen` an arbitrary native library before any managed code runs — functionally equivalent to `LD_PRELOAD` but not covered by the `LD_` prefix block. If the goal is comprehensive .NET env injection coverage, consider adding these to `blockedKeys` (and mirroring in the generated Swift file).

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 7f8400b

@ademczuk ademczuk force-pushed the fix/security-env-blocklist branch from 7b39412 to a021dd4 Compare March 17, 2026 13:36
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a021dd4611

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ademczuk ademczuk force-pushed the fix/security-env-blocklist branch from fe2d404 to 7f8400b Compare March 17, 2026 13:56
@ademczuk ademczuk closed this Mar 17, 2026
@ademczuk ademczuk reopened this Mar 17, 2026
@ademczuk
Copy link
Copy Markdown
Contributor Author

Regression risk note

These vars go into blockedKeys (stripped from inherited env AND user overrides), consistent with existing entries like NODE_OPTIONS and PYTHONPATH.

If someone runs their gateway on a host with JAVA_TOOL_OPTIONS=-javaagent:/opt/datadog/dd-java-agent.jar for APM, agent-spawned Java commands will silently lose the APM agent. Same pattern already accepted for NODE_OPTIONS (JVM monitoring) and PYTHONPATH (custom import paths).

In practice the overlap between "openclaw gateway host" and "JVM APM via env vars" is very small, and the security benefit (blocking -javaagent injection) outweighs the convenience loss.

"_JAVA_OPTIONS",
"JDK_JAVA_OPTIONS",
"PYTHONBREAKPOINT",
"DOTNET_STARTUP_HOOKS"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing .NET CLR profiler injection trio

DOTNET_STARTUP_HOOKS is now blocked (managed code injection), but the CLR profiler API is a parallel native-code injection vector that isn't caught by the existing LD_ prefix block:

Variable Role
CORECLR_ENABLE_PROFILING Activates the profiler (1 enables it)
CORECLR_PROFILER CLSID of the profiler COM object
CORECLR_PROFILER_PATH / CORECLR_PROFILER_PATH_64 Path to the native profiler .so/.dll loaded before Main()

Setting all three causes the .NET runtime to dlopen an arbitrary native library before any managed code runs — functionally equivalent to LD_PRELOAD but not covered by the LD_ prefix block. If the goal is comprehensive .NET env injection coverage, consider adding these to blockedKeys (and mirroring in the generated Swift file).

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/infra/host-env-security-policy.json
Line: 25

Comment:
**Missing .NET CLR profiler injection trio**

`DOTNET_STARTUP_HOOKS` is now blocked (managed code injection), but the CLR profiler API is a parallel native-code injection vector that isn't caught by the existing `LD_` prefix block:

| Variable | Role |
|---|---|
| `CORECLR_ENABLE_PROFILING` | Activates the profiler (`1` enables it) |
| `CORECLR_PROFILER` | CLSID of the profiler COM object |
| `CORECLR_PROFILER_PATH` / `CORECLR_PROFILER_PATH_64` | Path to the native profiler `.so`/`.dll` loaded before `Main()` |

Setting all three causes the .NET runtime to `dlopen` an arbitrary native library before any managed code runs — functionally equivalent to `LD_PRELOAD` but not covered by the `LD_` prefix block. If the goal is comprehensive .NET env injection coverage, consider adding these to `blockedKeys` (and mirroring in the generated Swift file).

How can I resolve this? If you propose a fix, please make it concise.

@ademczuk ademczuk merged commit f84a41d into openclaw:main Mar 17, 2026
59 of 73 checks passed
nikolaisid pushed a commit to nikolaisid/openclaw that referenced this pull request Mar 18, 2026
…ost exec sandbox (openclaw#49025)

Add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, and
DOTNET_STARTUP_HOOKS to blockedKeys in the host exec security policy.

Closes openclaw#22681
ssfdre38 pushed a commit to ssfdre38/openclaw-community-edition that referenced this pull request Mar 18, 2026
…ost exec sandbox (openclaw#49025)

Add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, and
DOTNET_STARTUP_HOOKS to blockedKeys in the host exec security policy.

Closes openclaw#22681
@ademczuk ademczuk deleted the fix/security-env-blocklist branch March 19, 2026 07:47
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 23, 2026
…ost exec sandbox (openclaw#49025)

Add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, and
DOTNET_STARTUP_HOOKS to blockedKeys in the host exec security policy.

Closes openclaw#22681

(cherry picked from commit f84a41d)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 23, 2026
…ost exec sandbox (openclaw#49025)

Add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, and
DOTNET_STARTUP_HOOKS to blockedKeys in the host exec security policy.

Closes openclaw#22681

(cherry picked from commit f84a41d)
ralyodio pushed a commit to ralyodio/openclaw that referenced this pull request Apr 3, 2026
…ost exec sandbox (openclaw#49025)

Add JAVA_TOOL_OPTIONS, _JAVA_OPTIONS, JDK_JAVA_OPTIONS, PYTHONBREAKPOINT, and
DOTNET_STARTUP_HOOKS to blockedKeys in the host exec security policy.

Closes openclaw#22681
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos maintainer Maintainer-authored PR size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] Environment variable blocklist incomplete — missing GLIBC_TUNABLES, JAVA_TOOL_OPTIONS, etc.

1 participant