hermes-agent/tools
Eugeniusz Gilewski 9078b4bbdf fix(file): harden read_file device alias blocking
Security-hardening fix for the read_file device guard, not a new sandbox
boundary. The guard already rejects direct device paths and upstream now
has a resolved-path pass for workspace symlinks to blocked devices, but
its concrete-path helper still compared the expanded path before
normalization. That leaves residual alias cases where the dangerous path
is visible before final terminal-specific resolution, for example:

  1. /dev/../dev/zero and /dev/./urandom should match the blocked-device
     list as concrete paths, not only after final realpath;
  2. /dev/stdin-style aliases can disappear once realpath follows them
     to /proc/self/fd/0 and then to a tty path;
  3. a user symlink to /dev/../dev/stdin exposes the dangerous
     intermediate target before final resolution, but not necessarily
     after it.

Normalize expanded paths before matching and inspect each symlink hop
before falling back to realpath. This preserves the existing /proc fd and
/proc pseudo-file guards while enforcing the intended security invariant:
model-supplied read paths must not reach blocking or infinite device
streams through spelling, normalization, or symlink-hop tricks.

Classification: security hardening / residual bypass fix for the
read_file device blocklist. This is defensive code at the file-tool
boundary, but it fixes a concrete denial-of-service class tracked as
security in #10141 and #29158.

Tests:
  - normalized /dev/../dev/zero and /dev/./urandom aliases
  - symlink to /dev/../dev/stdin blocked before realpath
  - existing symlink-to-device and regular-symlink guards still pass

Fixes #10141
Fixes #29158
2026-06-21 11:11:19 -07:00
..
computer_use fix(#37878): scrub operator environment before launching cua-driver MCP 2026-06-18 08:53:31 -07:00
environments fix: make profile subprocess HOME policy explicit 2026-06-14 03:20:21 -07:00
neutts_samples
__init__.py Merge branch 'main' into rewbs/tool-use-charge-to-subscription 2026-03-31 08:48:54 +09:00
ansi_strip.py fix: strip ANSI at the source — clean terminal output before it reaches the model 2026-03-23 07:43:12 -07:00
approval.py feat(tools): MCP elicitation handler with gateway-aware approval routing 2026-06-19 11:46:25 -07:00
async_delegation.py feat(delegation): background fan-out — parallel subagents, one consolidated return (#49734) 2026-06-20 11:27:12 -07:00
binary_extensions.py fix(tools): address PR review — remove _extract_raw_output, BudgetConfig everywhere, read_file hardening 2026-04-08 02:24:32 -07:00
blueprints.py refactor(cron): rebrand Cron Recipes -> Automation Blueprints 2026-06-11 10:49:47 -07:00
browser_camofox.py fix(browser): rewrite Camofox Docker loopback URLs (#25541) 2026-05-29 15:43:55 +10:00
browser_camofox_state.py feat(browser): add persistent Camofox sessions and VNC URL discovery (salvage #4400) (#4419) 2026-04-01 04:18:50 -07:00
browser_cdp_tool.py fix(deps): declare websockets as core dep + relax dev setuptools pin (salvage #45486, #44693) (#46744) 2026-06-15 12:44:44 -04:00
browser_dialog_tool.py feat: auto-launch Chromium-family browser for CDP 2026-05-19 22:34:05 -07:00
browser_supervisor.py fix(browser): recover from CDP DOM-node serialization crash in browser_console (#35385) 2026-05-30 07:31:25 -07:00
browser_tool.py fix(browser): enable SSRF guard when terminal runs in container 2026-06-21 07:26:18 -07:00
budget_config.py fix(agent): scale tool-output budget to the model context window (#23767) 2026-06-21 17:46:38 +05:30
checkpoint_manager.py fix(cron): compact cron failure messages + repair bare repo dirs after git gc 2026-06-19 07:35:29 -07:00
clarify_gateway.py feat(gateway): wire clarify tool with inline keyboard buttons on Telegram (#24199) 2026-05-12 16:33:33 -07:00
clarify_tool.py fix(clarify): docstring — put options in choices[] only, never enumerate in question text 2026-06-19 07:34:02 -07:00
code_execution_tool.py fix: make profile subprocess HOME policy explicit 2026-06-14 03:20:21 -07:00
computer_use_tool.py feat(computer-use): cua-driver backend, universal any-model schema 2026-05-08 11:07:38 -07:00
credential_files.py fix(slack): make video attachments available to agents (#45512) 2026-06-13 03:33:27 -07:00
cronjob_tools.py fix(cron): execute job immediately on action='run' 2026-06-21 13:28:04 +05:30
debug_helpers.py refactor: codebase-wide lint cleanup — unused imports, dead code, and inefficient patterns (#5821) 2026-04-07 10:25:31 -07:00
delegate_tool.py feat(delegation): background fan-out — parallel subagents, one consolidated return (#49734) 2026-06-20 11:27:12 -07:00
discord_tool.py feat: add Discord message deletion action 2026-05-07 05:11:09 -07:00
env_passthrough.py harden(env_passthrough): apply GHSA-rhgp-j443-p4rf filter to config.yaml path (#27794) 2026-05-25 03:35:23 -07:00
env_probe.py fix: prevent TUI gateway stdin EOF crash across all TUI-context subprocess calls 2026-06-08 22:46:57 -07:00
fal_common.py refactor(image_gen): port FAL backend to plugins/image_gen/fal 2026-05-22 04:10:45 -07:00
feishu_doc_tool.py perf(cli): cut ~19s from 'hermes' cold start (skills cache + lazy Feishu + no Nous HTTP) (#22138) 2026-05-08 16:39:32 -07:00
feishu_drive_tool.py perf(cli): cut ~19s from 'hermes' cold start (skills cache + lazy Feishu + no Nous HTTP) (#22138) 2026-05-08 16:39:32 -07:00
file_operations.py fix: warn on line-oriented newline search patterns 2026-06-20 23:23:47 -07:00
file_state.py feat(delegate): cross-agent file state coordination for concurrent subagents (#13718) 2026-04-21 16:41:26 -07:00
file_tools.py fix(file): harden read_file device alias blocking 2026-06-21 11:11:19 -07:00
fuzzy_match.py docs: clean up three stale comments from the #32848 audit (#45638) 2026-06-19 16:09:30 -07:00
homeassistant_tool.py fix: clean up description escaping, add string-data tests 2026-04-13 04:45:07 -07:00
image_generation_tool.py fix(tools): never let a model whitelist strip the prompt / source images 2026-06-19 16:59:54 -07:00
interrupt.py fix(interrupt): propagate to concurrent-tool workers + opt-in debug trace (#11907) 2026-04-17 20:39:25 -07:00
kanban_tools.py feat(kanban): auto-subscribe calling session on kanban_create 2026-06-18 14:10:51 -07:00
lazy_deps.py fix(dashboard): clean up upload temp file on client disconnect + pin python-multipart (NS-501) 2026-06-18 11:32:18 +05:30
managed_tool_gateway.py fix(managed-gateway): keep tool availability scans off the Nous token-refresh path 2026-05-30 07:58:08 -07:00
mcp_oauth.py fix(mcp): fail fast for noninteractive oauth without tokens 2026-06-15 04:22:07 -07:00
mcp_oauth_manager.py fix(mcp): fail fast for noninteractive oauth without tokens 2026-06-15 04:22:07 -07:00
mcp_tool.py fix(mcp): detect 'unknown method' phrasing in ping keepalive fallback 2026-06-21 16:02:56 +05:30
memory_tool.py fix(memory): recover from missing old_text on single-op replace/remove (#49997) 2026-06-20 23:46:52 -07:00
microsoft_graph_auth.py feat(msgraph): add auth and client foundation 2026-05-08 09:27:26 -07:00
microsoft_graph_client.py fix(msgraph): stream download_to_file body instead of buffering 2026-05-08 09:27:26 -07:00
mixture_of_agents_tool.py chore: ruff auto-fix C401, C416, C408, PLR1722 (#23940) 2026-05-11 11:20:58 -07:00
neutts_synth.py
openrouter_client.py
osv_check.py fix(osv_check): honor npx --package/-p install target when parsing package arg (#40567) 2026-06-06 18:30:39 -07:00
patch_parser.py fix(lint): skip per-file shell linter when LSP will handle the file (#29054) 2026-05-20 01:46:40 -05:00
path_security.py refactor: extract shared helpers to deduplicate repeated code patterns (#7917) 2026-04-11 13:59:52 -07:00
process_registry.py feat(delegation): background fan-out — parallel subagents, one consolidated return (#49734) 2026-06-20 11:27:12 -07:00
read_extract.py feat(read): extract notebook and office documents (#37082) 2026-06-13 14:42:51 -07:00
read_terminal_tool.py feat(desktop): resizable VS Code-themed terminal pane + palette polish (#42521) 2026-06-09 23:15:20 -05:00
registry.py security: sanitize tool error strings before injecting into model context (#26823) 2026-05-16 00:57:39 -07:00
schema_sanitizer.py fix(tools): strip default from $ref nodes in tool schemas 2026-06-12 00:30:51 -05:00
send_message_tool.py refactor(gateway): migrate slack/dingtalk/whatsapp/matrix/feishu/telegram/wecom/email/sms adapters to bundled plugins 2026-06-20 10:26:45 -07:00
session_search_tool.py docs(session-search): document source-first retrieval limits 2026-06-20 23:23:47 -07:00
skill_manager_tool.py feat(display): verbose skill change notifications with content previews 2026-06-16 05:45:40 -07:00
skill_provenance.py fix(curator): only mark agent-created for background-review sediment (#19621) 2026-05-04 02:42:16 -07:00
skill_usage.py fix(curator): stop restore from matching unrelated skills by name prefix 2026-06-17 06:04:03 -07:00
skills_ast_audit.py refactor(skills): slim AST diagnostic to single entry point 2026-05-23 17:47:26 -07:00
skills_guard.py fix(skills-guard): stop flagging benign skill content + honor skill ignore files (#36231) 2026-06-01 01:58:48 -07:00
skills_hub.py fix(skills): let ClawHub index build walk past the 12s browse budget (#44500) 2026-06-11 18:03:11 -04:00
skills_sync.py fix(skills): refuse SKILLS_DIR root in rmtree guard, not just outside-tree 2026-06-18 08:53:35 -07:00
skills_tool.py fix(skills): ignore support docs in skill discovery 2026-06-16 13:08:34 -07:00
slash_confirm.py fix(async): close unscheduled coroutines in all threadsafe bridges (#26584) 2026-05-15 14:00:01 -07:00
terminal_tool.py fix(terminal): block gateway lifecycle commands from inside the gateway process 2026-06-19 11:53:44 +05:30
thread_context.py fix(code-exec): propagate agent-turn context into tool worker threads 2026-05-29 03:44:49 -07:00
threat_patterns.py feat(security): promptware defense — shared threat patterns + memory load-time scan + tool-result delimiters (#32269) 2026-05-25 14:52:24 -07:00
tirith_security.py fix: prevent TUI gateway stdin EOF crash across all TUI-context subprocess calls 2026-06-08 22:46:57 -07:00
todo_tool.py hardening(todo): bound TodoStore item content length and count 2026-06-07 18:06:27 -07:00
tool_backend_helpers.py feat(tools): surface the free tool pool in entitlement + setup (#36153) 2026-06-01 06:32:48 +05:30
tool_output_limits.py fix: tool_output_limits re-reads config on every call (no caching) 2026-05-31 00:50:19 -07:00
tool_result_storage.py fix(tool-result-storage): persist via stdin to bypass 128 KB exec-arg cap (#22913) 2026-05-09 18:44:58 -07:00
tool_search.py fix(tool-search): scope bridge catalog + dispatch to the session's toolsets 2026-05-29 02:04:12 -07:00
transcription_tools.py fix: prevent TUI gateway stdin EOF crash across all TUI-context subprocess calls 2026-06-08 22:46:57 -07:00
tts_tool.py feat(tts): add xAI TTS speed and optimize_streaming_latency config knobs 2026-06-19 07:26:56 -07:00
url_safety.py fix(tools): percent-encode non-ascii URL components 2026-06-07 11:42:26 -06:00
video_generation_tool.py fix(xai): route video models by modality 2026-06-01 19:00:30 -07:00
vision_tools.py fix(deps): force prompt=False on the two mid-session lazy-install tool paths 2026-06-06 18:44:15 -07:00
voice_mode.py fix: prevent TUI gateway stdin EOF crash across all TUI-context subprocess calls 2026-06-08 22:46:57 -07:00
web_tools.py revert(web): remove keyless Parallel search fallback (#46350) 2026-06-14 16:47:57 -07:00
website_policy.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
write_approval.py fix(memory,skills): repair write-approval inline prompt, gateway staging, and gateway /skills review (#43452) 2026-06-10 02:57:15 -07:00
x_search_tool.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
xai_http.py feat(web): add xAI Web Search provider plugin 2026-05-19 19:27:34 -07:00
yuanbao_tools.py Fix unsafe gateway media path delivery 2026-05-23 01:40:35 -07:00