security: harden default tool policies and secure shell execution#16320
security: harden default tool policies and secure shell execution#16320SuccessSoham wants to merge 8 commits intoopenclaw:mainfrom
Conversation
Additional Comments (1)
Prompt To Fix With AIThis is a comment left during a code review.
Path: src/process/exec.ts
Line: 88:88
Comment:
**Unused destructured variable**
`windowsVerbatimArguments` is destructured from `options` here but never used — the spawn call on line 130 uses `isCmdBatch` instead. This should either be removed (if the option is intentionally deprecated) or used in the spawn call (see comment on line 130).
How can I resolve this? If you propose a fix, please make it concise. |
|
This Pull Request addresses the security vulnerabilities documented in issue #16323. |
aa018b6 to
8a32ebb
Compare
|
I have updated the PR to address the suggestions from @greptile-apps:
|
…anks Soham) Implementation details: - Enforce 'Deny-All' default tool policy for untrusted users in pi-tools.policy.ts. - Propagate 'senderIsOwner' context through tool filtering in pi-tools.ts. - Explicitly clear unauthorized /exec directives in get-reply-directives.ts to prevent privilege escalation. - Secure Windows shell execution in process/exec.ts by explicitly using 'cmd.exe /c' for batch files and disabling implicit shell. - Enhance security audit in audit.ts to flag critical trusted-proxy misconfigurations.
8a32ebb to
1a54e1e
Compare
bfc1ccb to
f92900f
Compare
| "This allows anyone who can reach the gateway port to spoof user identity.", | ||
| remediation: "Set gateway.trustedProxies to the specific IP(s) of your reverse proxy.", |
There was a problem hiding this comment.
Audit detail contradicts actual runtime behavior
The new message claims empty trustedProxies "allows anyone who can reach the gateway port to spoof user identity," but authorizeGatewayConnect in src/gateway/auth.ts:318-319 explicitly returns { ok: false, reason: "trusted_proxy_no_proxies_configured" } when the list is empty — meaning all requests are rejected, not spoofable.
The original wording ("All requests will be rejected.") was accurate. This change introduces a misleading audit finding that could cause operators to misdiagnose the actual problem (a denial-of-service to themselves, not an identity spoofing vulnerability).
| "This allows anyone who can reach the gateway port to spoof user identity.", | |
| remediation: "Set gateway.trustedProxies to the specific IP(s) of your reverse proxy.", | |
| "This configuration rejects all incoming requests since no proxy is trusted. " + | |
| "Set gateway.trustedProxies to allow traffic from your reverse proxy.", | |
| remediation: "Set gateway.trustedProxies to the specific IP(s) of your reverse proxy.", |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/security/audit.ts
Line: 402:403
Comment:
**Audit detail contradicts actual runtime behavior**
The new message claims empty `trustedProxies` "allows anyone who can reach the gateway port to spoof user identity," but `authorizeGatewayConnect` in `src/gateway/auth.ts:318-319` explicitly returns `{ ok: false, reason: "trusted_proxy_no_proxies_configured" }` when the list is empty — meaning all requests are **rejected**, not spoofable.
The original wording ("All requests will be rejected.") was accurate. This change introduces a misleading audit finding that could cause operators to misdiagnose the actual problem (a denial-of-service to themselves, not an identity spoofing vulnerability).
```suggestion
"This configuration rejects all incoming requests since no proxy is trusted. " +
"Set gateway.trustedProxies to allow traffic from your reverse proxy.",
remediation: "Set gateway.trustedProxies to the specific IP(s) of your reverse proxy.",
```
How can I resolve this? If you propose a fix, please make it concise.|
This pull request has been automatically marked as stale due to inactivity. |
|
This pull request has been automatically marked as stale due to inactivity. |
|
Closing due to inactivity. |
Security Improvements
This PR implements several security hardenings identified during a recent audit.
1. Default Tool Policy Hardening (Critical)
exec) to untrusted users in default configurations.isToolAllowedByPolicyNameinsrc/agents/pi-tools.policy.tsto default tofalse(deny-all).senderIsOwnerparameter to policy checks. Only verified owners bypass the policy check when no policy is present. All other users are denied by default if no explicit policy allows access.2. Privilege Escalation Fix (High)
/execdirectives (e.g.host=gateway) persisted in the session context even when the sender was not authorized to run commands.src/auto-reply/reply/get-reply-directives.tsto explicitly clearhasExecDirectiveand related fields whencommandAuthorizedis false.3. Secure Windows Shell Execution (High)
runCommandWithTimeoutusedshell: trueimplicitly for non-exe files on Windows, which is vulnerable to command injection via shell metacharacters in arguments.src/process/exec.tsto explicitly detect batch files (.cmd,.bat) and execute them usingcmd.exe /cwithwindowsVerbatimArguments: true. All other executions now useshell: false.4. Audit Enhancements (Medium)
trusted-proxyauth mode is insecure iftrustedProxiesis empty, allowing header spoofing.src/security/audit.tsto flag emptytrustedProxiesconfiguration whentrusted-proxymode is enabled.Verification
pnpm buildpasses.Thanks to @SuccessSoham for the contribution.
Greptile Summary
This PR hardens security defaults across tool policies, exec directive handling, Windows shell execution, and audit messaging. The most impactful change is the deny-by-default policy in
isToolAllowedByPolicyNamewhen no explicit policy is configured, with ansenderIsOwnerbypass for verified owners. All call sites have been updated to propagate the new parameter.pi-tools.policy.ts): Changed from allow-all to deny-all when no policy exists; only verified owners bypass. ThesenderIsOwnerparameter is correctly threaded throughfilterToolsByPolicy,isToolAllowedByPolicies, andapplyToolPolicyPipeline.get-reply-directives.ts): Unauthorized senders now have exec directive fields cleared to prevent privilege escalation of/execdirectives persisting in session context.exec.ts): Replaces implicitshell: truewith explicitcmd.exe /cfor.cmd/.batfiles andshell: falseeverywhere else. Caller-suppliedwindowsVerbatimArgumentsis honored via||fallback.audit.ts): The updated detail text for emptytrustedProxiesis factually incorrect — the gateway rejects all requests in this case (seesrc/gateway/auth.ts:318-319), it does not allow identity spoofing. This should be corrected before merge.audit-extra.async.ts,audit-extra.sync.ts): PasssenderIsOwner: trueto preserve worst-case exposure modeling in audit checks.Confidence Score: 3/5
Last reviewed commit: fba4dee