hermes-agent/tools
Teknium 69a293b419 hardening(todo): bound TodoStore item content length and count
The todo list is re-injected into the model's context after every
context-compression event (TodoStore.format_for_injection), so an oversized
todo item or an unbounded number of items defeats the compression it is meant
to ride through. TodoStore.write/_validate previously enforced no size or count
bounds, so a single 50KB item produced a ~50KB re-injection block on every
subsequent turn.

Add two caps:
- MAX_TODO_CONTENT_CHARS (4000): per-item content is truncated with a marker.
  Routed through a shared _cap_content() so the merge-update path (which writes
  content directly, bypassing _validate) is capped too.
- MAX_TODO_ITEMS (256): total list length is bounded, keeping the
  highest-priority head (list order is priority).

Both caps are generous relative to real plans — a todo item is a short task
description and active lists are a handful of items.

NOT a security fix. Raised externally via GHSA-5g4g-6jrg-mw3g, which framed a
caller-supplied conversation_history on the authenticated API server replaying
into _hydrate_todo_store as a DoS. That path is authenticated (the API server
refuses to start without API_SERVER_KEY) and self-scoped (the caller supplies
their own entire history and can only inflate their own response chain — forged
role=tool entries are never persisted to the session DB), so it is out of scope
as a vulnerability under SECURITY.md 3.2. These bounds are footgun containment
that also applies to the trusted agent path, where the model itself authors the
todos. Credit to the reporter for the observation.

Co-authored-by: YLChen-007 <30854794+YLChen-007@users.noreply.github.com>
2026-06-07 18:06:27 -07:00
..
computer_use fix(computer_use): honor custom vision routing 2026-06-07 02:09:20 -07:00
environments fix(tui): preserve remote cwd for ssh sessions 2026-06-06 18:40:43 -07:00
neutts_samples
__init__.py
ansi_strip.py
approval.py fix(security): strip shell escapes in denylist normalizer; fail-closed on missing approval module 2026-06-07 03:57:21 -07:00
binary_extensions.py
browser_camofox.py fix(browser): rewrite Camofox Docker loopback URLs (#25541) 2026-05-29 15:43:55 +10:00
browser_camofox_state.py
browser_cdp_tool.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07: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(tools): percent-encode non-ascii URL components 2026-06-07 11:42:26 -06:00
budget_config.py
checkpoint_manager.py fix: guard int(os.getenv()) casts against malformed env vars (#40598) 2026-06-07 06:14:24 -07:00
clarify_gateway.py
clarify_tool.py
code_execution_tool.py fix(code-exec): make dropped HERMES_* env vars diagnosable in sandbox scrub 2026-05-29 03:44:49 -07:00
computer_use_tool.py
credential_files.py refactor(image_gen): delegate cache-path mapping to shared helper 2026-06-06 13:19:07 -07:00
cronjob_tools.py fix(cron): sanitize invisible unicode in vetted skill content instead of hard-blocking (#37245) 2026-06-02 00:29:44 -07:00
debug_helpers.py
delegate_tool.py fix(delegate): flatten content blocks in live overlay tail + AUTHOR_MAP 2026-06-05 23:34:00 -07:00
discord_tool.py
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 feat(prompt): universal task-completion guidance + local Python toolchain probe (#34340) 2026-05-28 22:26:09 -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
feishu_drive_tool.py
file_operations.py fix(file-ops): make rg/grep search error guard reachable and preserve partial matches (#39858) 2026-06-05 17:44:52 -07:00
file_state.py
file_tools.py fix(file-safety): extend sandbox-mirror guard to cover inner-container path (#32049) (#32407) 2026-06-02 14:03:37 +10:00
fuzzy_match.py fix(patch): widen new_string \t/\r unescape to all match strategies (#33733) 2026-05-28 03:27:20 -07:00
homeassistant_tool.py
image_generation_tool.py refactor(image_gen): delegate cache-path mapping to shared helper 2026-06-06 13:19:07 -07:00
interrupt.py
kanban_tools.py fix(kanban): kanban_create inherits the spawning worker's task workspace (#37182) 2026-06-01 21:26:29 -07:00
lazy_deps.py fix(deps): force prompt=False on the two mid-session lazy-install tool paths 2026-06-06 18:44:15 -07:00
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 feat(mcp-oauth): accept 'skip' at paste prompt to bypass auth without disabling server (#32069) 2026-05-25 05:37:30 -07:00
mcp_oauth_manager.py
mcp_tool.py fix: skip MCP preflight content-type probe on reconnect when already ready (#40604) 2026-06-07 09:51:11 -07:00
memory_tool.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
microsoft_graph_auth.py
microsoft_graph_client.py
mixture_of_agents_tool.py
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
process_registry.py feat(desktop): session hygiene, archive, media streaming + connecting overlay (#37099) 2026-06-01 20:41:34 -05:00
registry.py
schema_sanitizer.py fix(xai-responses): strip enum values containing '/' from tool schemas 2026-05-18 10:37:35 -07:00
send_message_tool.py refactor(gateway): migrate Home Assistant adapter to bundled plugin 2026-06-06 11:46:24 -07:00
session_search_tool.py feat(desktop): drag sessions into chat as @session links + spawn loader 2026-06-04 19:41:51 -05:00
skill_manager_tool.py fix(skill_manager): allow SKILL.md in _validate_file_path without weakening traversal guard (#40568) 2026-06-06 18:32:37 -07:00
skill_provenance.py
skill_usage.py feat(curator): prune built-in skills after inactivity + track usage for all skills (#36701) 2026-06-01 02:07:32 -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 feat(skills): categorize tap skills from skills.sh.json grouping sidecar 2026-05-29 12:24:39 -07:00
skills_sync.py feat(skills): blank-slate skills — install --no-skills + opt-out/opt-in (#36228) 2026-06-01 02:57:57 -07:00
skills_tool.py fix(skills): block path traversal via skill_view name argument (#40566) 2026-06-06 18:29:52 -07:00
slash_confirm.py
terminal_tool.py fix(terminal): guard os.getcwd() against a deleted CWD 2026-06-04 23:39:34 -07:00
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(tirith): reject non-regular tar members during auto-install process 2026-05-28 02:49:26 -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
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(transcription): handle ffmpeg TimeoutExpired in _prepare_local_audio 2026-06-07 01:26:33 -07:00
tts_tool.py fix(tools): add raise_for_status for MiniMax t2a_v2 TTS path 2026-06-04 06:17:11 -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(voice): allow /voice over SSH when a sound server is reachable (#35719) 2026-05-31 00:11:52 -07:00
web_tools.py fix(web): make _has_env config-aware so SEARXNG_URL auto-detect honors Hermes config 2026-06-08 01:12:32 +05:30
website_policy.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -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