You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix a sandbox tool-isolation bypass in execute_code.
Previously, when a session passed an explicit enabled_tools list that had no overlap with sandbox tools, Hermes silently fell back to granting all sandbox tools. In practice, this allowed a session with only execute_code enabled to regain capabilities such as terminal, file operations, and web access from inside the sandbox.
This change enforces the boundary consistently by introducing _resolve_sandbox_tools() and using it in both sandbox call paths.
What changed
added _resolve_sandbox_tools() in tools/code_execution_tool.py:77
switched both local and remote sandbox call sites to use it:
tools/code_execution_tool.py:715
tools/code_execution_tool.py:923
preserved backward-compatible fallback only when enabled_tools is None
prevented privilege expansion when enabled_tools is an explicit empty list or an explicit list with no overlap with sandbox tools
added regression coverage:
platform-independent boundary tests in tests/tools/test_code_execution.py:120
exploit-oriented regression test in tests/tools/test_code_execution.py:733
Why
This was a security boundary issue.
Before this fix, explicit tool restrictions could be bypassed inside the execute_code sandbox because non-overlapping tool lists were treated the same as “no restriction provided,” causing Hermes to re-enable all sandbox tools. That behavior violated caller intent and expanded privileges unexpectedly.
The new resolution logic distinguishes between:
enabled_tools is None → keep legacy fallback behavior
explicit empty list / explicit non-overlapping list → do not widen permissions
Security impact
High severity.
A session intended to expose only execute_code could previously regain access to:
terminal
read_file
write_file
web access
This PR closes that isolation bypass and makes the sandbox honor explicit tool constraints.
This is a critical hardening measure. Without strict tool isolation within the execute_code sandbox, there's a risk of privilege escalation or unintended side-channel access to host resources.\n\nHave you considered adding explicit integration tests that attempt to access restricted tools (like terminal or memory) from within a spawned execute_code process? This would provide concrete validation that the isolation boundaries are holding.\n\nAlso, worth double-checking if this change impacts any existing workflows that rely on legacy behaviors—though in a security context, breaking changes are often necessary and expected.
Recommendation: needs rework/rebase before merge. The security invariant is valid, but the PR patch is stale against current upstream/main.
Checked current upstream/main as published by GitHub at 3c73d1852e372d1fe03dc5931d2f95be059caa67 and PR head 832d595c819e146636ff7d786e71cdbb86ebc73b.
Evidence:
Current main still reproduces the bypass: a focused execute_code(..., enabled_tools=["execute_code"]) probe can import terminal from hermes_tools and returns status=success.
PR head blocks the same probe with ImportError: cannot import name 'terminal' from 'hermes_tools'.
Current-main legacy fallback tests still pass: test_empty_enabled_tools_uses_all and test_nonoverlapping_tools_fallback -> 2 passed, confirming the current behavior still widens access.
Integration check fails: git apply --check pr6614.patch against current main fails in both tools/code_execution_tool.py and tests/tools/test_code_execution.py, so this branch is not mergeable as-is.
CodeRabbit was run on the reconstructed original-base PR diff (coderabbit review --plain --base HEAD~1 --type committed) and reported no findings. coderabbit doctor still reports the known local storage failure for /home/mac/.coderabbit, but service/auth/network checks passed and the review completed.
Suggested next step: rebase/adapt the same _resolve_sandbox_tools() semantics to current tools/code_execution_tool.py line positions, preserving the enabled_tools is None legacy fallback while treating any explicit list as authoritative.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
P0Critical — data loss, security, crash looptool/code-execexecute_code sandboxtype/securitySecurity vulnerability or hardening
6 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix a sandbox tool-isolation bypass in
execute_code.Previously, when a session passed an explicit
enabled_toolslist that had no overlap with sandbox tools, Hermes silently fell back to granting all sandbox tools. In practice, this allowed a session with onlyexecute_codeenabled to regain capabilities such as terminal, file operations, and web access from inside the sandbox.This change enforces the boundary consistently by introducing
_resolve_sandbox_tools()and using it in both sandbox call paths.What changed
_resolve_sandbox_tools()intools/code_execution_tool.py:77tools/code_execution_tool.py:715tools/code_execution_tool.py:923enabled_tools is Noneenabled_toolsis an explicit empty list or an explicit list with no overlap with sandbox toolstests/tools/test_code_execution.py:120tests/tools/test_code_execution.py:733Why
This was a security boundary issue.
Before this fix, explicit tool restrictions could be bypassed inside the
execute_codesandbox because non-overlapping tool lists were treated the same as “no restriction provided,” causing Hermes to re-enable all sandbox tools. That behavior violated caller intent and expanded privileges unexpectedly.The new resolution logic distinguishes between:
enabled_tools is None→ keep legacy fallback behaviorSecurity impact
High severity.
A session intended to expose only
execute_codecould previously regain access to:read_filewrite_fileThis PR closes that isolation bypass and makes the sandbox honor explicit tool constraints.
How to test
Ran: