mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
_scan_cron_prompt ran at cron create/update time on the user-supplied prompt but skill content loaded inside _build_job_prompt at runtime was never scanned. Combined with non-interactive auto-approval, a malicious skill carrying an injection payload could execute with full tool access every tick. - cron/scheduler.py: new CronPromptInjectionBlocked exception and _scan_assembled_cron_prompt helper. _build_job_prompt now routes both return paths (with skills / without skills) through the helper, raising on match. run_job catches the exception and returns a clean (False, blocked_doc, "", error) tuple so the operator sees a BLOCKED delivery with the scanner result and an audit hint, rather than a scheduler crash or a silent skip. - tests/cron/test_cron_prompt_injection_skill.py: 10 regression tests. Unit coverage on _scan_assembled_cron_prompt (clean/injection/exfil/ invisible-unicode). End-to-end coverage via _build_job_prompt with planted skills (injection payload, env exfil, zero-width space, clean control, missing-skill-doesn't-crash). Fixture patches tools.skills_tool.SKILLS_DIR / HERMES_HOME so planted skills are visible. Importantly uses the current cron.scheduler module object (not a top-level import) so tests don't break when other fixtures reload cron.scheduler — CronPromptInjectionBlocked identity depends on which module object defined it. |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| test_codex_execution_paths.py | ||
| test_compute_next_run_last_run_at.py | ||
| test_cron_context_from.py | ||
| test_cron_inactivity_timeout.py | ||
| test_cron_no_agent.py | ||
| test_cron_prompt_injection_skill.py | ||
| test_cron_script.py | ||
| test_cron_workdir.py | ||
| test_file_permissions.py | ||
| test_jobs.py | ||
| test_rewrite_skill_refs.py | ||
| test_scheduler.py | ||