|
1 | 1 | /** |
2 | 2 | * Server-side execution logic for the Hermes Agent adapter. |
3 | 3 | * |
4 | | - * Spawns `hermes chat -q - -Q` as a child process (prompt delivered via |
5 | | - * stdin, NOT as an argv element), streams output, and returns structured |
6 | | - * results to Paperclip. |
7 | | - * |
8 | | - * Security note: passing the prompt as an argv element (`-q "<prompt>"`) is |
9 | | - * unsafe — the full text (including wake context, task body, agent |
10 | | - * instructions, and API credentials guidance) is visible to any process that |
11 | | - * can read /proc/<pid>/cmdline or run `ps aux` on the same host. We pass the |
12 | | - * sentinel `-` instead and write the prompt to stdin, matching the pattern |
13 | | - * used by the claude-local adapter. See TRA-257 / TRA-256. |
| 4 | + * Spawns `hermes chat -q "..." -Q` as a child process, streams output, |
| 5 | + * and returns structured results to Paperclip. |
14 | 6 | * |
15 | 7 | * Verified CLI flags (hermes chat): |
16 | | - * -q/--query single query; `-q -` reads the query from stdin |
| 8 | + * -q/--query single query (non-interactive) |
17 | 9 | * -Q/--quiet quiet mode (no banner/spinner, only response + session_id) |
18 | 10 | * -m/--model model name (e.g. anthropic/claude-sonnet-4) |
19 | 11 | * -t/--toolsets comma-separated toolsets to enable |
@@ -425,13 +417,7 @@ export async function execute( |
425 | 417 | // ── Build command args ───────────────────────────────────────────────── |
426 | 418 | // Use -Q (quiet) to get clean output: just response + session_id line |
427 | 419 | const useQuiet = cfgBoolean(config.quiet) === true; // default false |
428 | | - // SECURITY FIX (TRA-257): pass `-q -` so hermes reads the prompt from stdin |
429 | | - // instead of argv. Passing the prompt as an argv element exposes the full |
430 | | - // rendered text (task body, wake context, API guidance) to any local process |
431 | | - // that can read /proc/<pid>/cmdline or run `ps aux`. The sentinel `-` tells |
432 | | - // hermes to read the query from stdin; the actual prompt is delivered via the |
433 | | - // `stdin` option of runChildProcess below. |
434 | | - const args: string[] = ["chat", "-q", "-"]; |
| 420 | + const args: string[] = ["chat", "-q", prompt]; |
435 | 421 | if (useQuiet) args.push("-Q"); |
436 | 422 |
|
437 | 423 | if (model) { |
@@ -549,7 +535,6 @@ export async function execute( |
549 | 535 | const result = await runChildProcess(ctx.runId, hermesCmd, args, { |
550 | 536 | cwd, |
551 | 537 | env, |
552 | | - stdin: prompt, // SECURITY FIX (TRA-257): deliver prompt via stdin, not argv |
553 | 538 | timeoutSec, |
554 | 539 | graceSec, |
555 | 540 | onLog: wrappedOnLog, |
|
0 commit comments