fix(tui_gateway): scrub credentials from shell.exec subprocess env - #60423
fix(tui_gateway): scrub credentials from shell.exec subprocess env#60423Da7-Tech wants to merge 3 commits into
Conversation
|
Thanks for the focused hardening change. Current main confirms the gap: The proposed This is an automated hermes-sweeper review. |
355fba9 to
801ab30
Compare
|
Rebased and revalidated on current Validation completed:
GitHub reports the PR mergeable. |
801ab30 to
6da95b9
Compare
|
Follow-up hardening is complete in |
6da95b9 to
0e3e219
Compare
|
Final follow-up is complete in Validation includes 3 focused tests on the final head, a 227-test relevant suite, Ruff, Python compilation, Windows-footgun and whitespace checks, an AST audit of both |
The shell.exec JSON-RPC handler ran subprocess.run(shell=True) without an explicit env, so the spawned shell inherited the full gateway process environment, including provider credentials and always-stripped infrastructure or messaging secrets. Pass hermes_subprocess_env(inherit_credentials=False) so both stripping tiers apply while benign variables such as PATH remain available. Add handler-level regression coverage for a provider key, a captured explicit env, and a live env probe spanning provider, GitHub, messaging, infrastructure, auxiliary-model, and gateway-relay secret classes. Assert the multi-class coverage on the actual env dict passed to subprocess.run rather than the handler's stdout, which is truncated to the last 4000 characters: on a large-environment host a benign trailing variable falls outside that window (false failure), and a leaked secret rendered before it would pass unnoticed (false pass). A dedicated regression constructs the leaked dump, shows the secret lands outside the 4000-char window while stdout looks clean, then proves the env-dict check catches it; the capture helper fails loudly if the handler ever stops passing an explicit env.
e3a16cb to
8a01ebe
Compare
|
Bound to the child-process credential-inheritance class under #83565 (#83565) — same bug class, different surface. tui_gateway shell.exec scrub; Wave D — merge lane established via #78036; currently dirty. The EPIC carries the live class table, dedup adjudication, and the dependency-driven merge order. |
…nitize-env Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # tui_gateway/server.py
What does this PR do?
Prevents the TUI gateway
shell.execJSON-RPC handler from passing the gateway process's full environment to a user-requested shell command.Before this change, the handler called
subprocess.run(..., shell=True)without an explicitenv, so the child inherited provider credentials, GitHub credentials, messaging tokens, infrastructure secrets, and Hermes-internal routing credentials fromos.environ.Type of change
Changes Made
hermes_subprocess_env(inherit_credentials=False)result to theshell.execsubprocess.shell.execdoes not need model credentials.PATH.shell.exechandler, asserting on the captured child environment rather than the handler's 4000-character-truncated stdout;PATHremain available;subprocess.runcall and prove an explicit sanitized environment is supplied.The sibling quick-command
shell=Trueroute already used its own sanitized environment and is unchanged. Thecli.execroute intentionally useshermes_subprocess_env(inherit_credentials=True)because it can launch the model-driving Hermes CLI; Tier-1 and Hermes-internal secrets remain stripped there by the central helper.How to Test
Verification Results
Three independent verification methods passed, with the final branch head at
8a01ebe4e:shell=Truecalls intui_gateway/server.pyand confirmed that both pass an explicit sanitizedenv.shell.exechandler with synthetic provider, GitHub, messaging, infrastructure, auxiliary-model, and gateway-relay secrets. All six credential classes were absent from the child, whilePATHand a benign canary variable were preserved.The dangerous-command detector also remained active: the live verification used the allowed
envcommand rather than bypassing or weakening command screening.Scope
This PR deliberately reuses the repository's central subprocess-environment policy. It does not add another sanitizer, alter credential classification, change the quick-command route, or broaden shell execution permissions.
Checklist