fix(executor): block proxy env var unset commands#307
Conversation
Agent-supplied commands could unset HTTPS_PROXY/HTTP_PROXY in the child shell before making outbound requests, silently bypassing the vault MITM proxy. Reject any command matching `unset (HTTPS|HTTP)_PROXY` with 403. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Greptile SummaryThis PR adds a regex guard to
Confidence Score: 2/5The security guard introduced by this PR can be bypassed via common shell idioms, leaving the vault MITM proxy unenforced for commands that don't use the exact The change is a targeted security hardening measure, but the regex it relies on is incomplete — at least three bypass paths ( harnesses/executor/src/server.ts — the new
|
| Filename | Overview |
|---|---|
| harnesses/executor/src/server.ts | Adds a regex guard to block unset HTTPS_PROXY-style commands, but the pattern misses several common shell bypass paths (env -u, inline HTTPS_PROXY=, and unset -v), leaving the proxy enforcement incomplete. |
Reviews (1): Last reviewed commit: "fix(executor): block proxy env var unset..." | Re-trigger Greptile
| }); | ||
|
|
||
| // Block commands that attempt to unset or clear the vault proxy env vars. | ||
| const PROXY_TAMPER_RE = /unset\s+(https?_proxy|HTTPS?_PROXY)\b/i; |
There was a problem hiding this comment.
Multiple shell bypass paths miss the
unset keyword entirely
The regex only intercepts the literal unset HTTPS_PROXY form, but a shell command passed to execAsync can clear or override the proxy variable in several other ways that the guard never sees:
env -u HTTPS_PROXY curl https://example.com— POSIX-standard per-command env removal, nounsetkeywordHTTPS_PROXY= curl https://example.com— inline empty-string override, proxy effectively disabled for that processunset -v HTTPS_PROXY— bash flag between the keyword and the variable name breaks the\s+(HTTPS?_PROXY)sequence in the regex
All three forms would pass the check and reach execAsync, silently bypassing the vault MITM proxy.
| }); | ||
|
|
||
| // Block commands that attempt to unset or clear the vault proxy env vars. | ||
| const PROXY_TAMPER_RE = /unset\s+(https?_proxy|HTTPS?_PROXY)\b/i; |
There was a problem hiding this comment.
| function rejectsProxyTamper(cmd: string): boolean { | ||
| return PROXY_TAMPER_RE.test(cmd); | ||
| } |
There was a problem hiding this comment.
Misleading predicate name — reads as an action, not a test
A boolean predicate that returns true when a command contains a proxy-tampering pattern should read as a question (isProxyTamper, detectsProxyTamper). The current name rejectsProxyTamper implies the function performs the rejection itself, which is confusing when reading the call-site if (rejectsProxyTamper(cmd)).
| function rejectsProxyTamper(cmd: string): boolean { | |
| return PROXY_TAMPER_RE.test(cmd); | |
| } | |
| function isProxyTamper(cmd: string): boolean { | |
| return PROXY_TAMPER_RE.test(cmd); | |
| } |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
unset HTTPS_PROXY(orHTTP_PROXY) in the child shell before making outbound requests, silently bypassing the vault MITM proxyPOST /executethat rejects any command matchingunset (HTTPS|HTTP)_PROXYwith a 403 beforeexecAsyncis calledTest plan
POST /executewithcmd: "unset HTTPS_PROXY && curl https://example.com"→ expect 403command blocked: proxy env vars cannot be unsetPOST /executewithcmd: "unset https_proxy"→ expect 403cmd: "echo hello") → expect 200 with output🤖 Generated with Claude Code