If you discover a security vulnerability in dynamic-model-delegation, please do not open a public issue. Instead, report it privately:
- Email: Open an issue with the title
[SECURITY]and describe the vulnerability - Response time: We aim to respond within 48 hours
- Disclosure: After a fix is released, we will credit the reporter (unless anonymity is requested)
- Spawn
hermes chat -qsubprocesses with model-specific-mflags - Read task definitions from JSON (argv or stdin)
- Write results to stdout as JSON
- Use the
workdirfield ascwdfor subprocess execution (validated to absolute, existing paths only)
- Execute arbitrary shell commands (uses list-based
create_subprocess_exec, no shell) - Access credentials (model strings are public identifiers; API keys are read by
hermes, not this script) - Modify files outside the specified
workdir - Bypass Hermes Agent's own security controls (
redact_secrets,tirith, etc.)
| Threat | Defense | Implemented |
|---|---|---|
| Shell injection via goal text | List-based args (create_subprocess_exec(*list)) — no shell invoked |
orchestrate.py:109-115 |
| Path traversal via workdir | Validated as absolute path + os.path.isdir() check |
orchestrate.py:160-166 (both engines) |
| Malicious model strings | Provider prefix validated against allowlist (VALID_PROVIDERS) |
orchestrate.py:87-93 |
| Memory DoS (1000+ tasks) | MAX_TASKS=50 hard cap |
orchestrate.py:317-323 |
| Zombie processes | terminate → 5s grace → kill → finally kill cascade | orchestrate.py:228-246 |
| Pipe buffer deadlock | communicate() reads both streams concurrently |
orchestrate.py:207-212 |
| Cancelled result loss | except BaseException catches CancelledError |
orchestrate.py:264-281 |
- Credential exfiltration via malicious PR: The orchestrator inherits the full environment including API keys. A malicious code change could exfiltrate them. Mitigation: human code review required for all PRs. No automated CI/secret scanning yet.
- Rate limit exhaustion: Tasks are dispatched to real model providers. An attacker can exhaust API rate limits by submitting many tasks. Mitigation:
MAX_TASKS=50cap,Semaphore(3)concurrency gate, and each task consumes one API call.
| Version | Supported |
|---|---|
| 1.0.x | ✅ Security fixes |
This skill follows the principle of least privilege: it does only what's needed to spawn model-specific subprocesses. Every input is validated. Every subprocess is cleaned up. Every attack surface identified during red-teaming has been hardened.