fix(gateway/auth): local trusted-proxy fallback to require token auth#54536
fix(gateway/auth): local trusted-proxy fallback to require token auth#54536vincentkoc merged 11 commits intomainfrom
Conversation
Greptile SummaryThis PR closes a localhost auth-bypass in Key changes:
One minor nit: the explanatory comment about not calling Confidence Score: 5/5
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/gateway/auth.ts
Line: 390-392
Comment:
**Dropped "don't burn rate-limit slots" rationale**
The original token-auth block had an explicit comment explaining why `token_missing` intentionally skips `recordFailure`:
```
// Don't burn rate-limit slots for missing credentials — the client
// simply hasn't provided a token yet (e.g. bare browser open).
// Only actual *wrong* credentials should count as failures.
```
The behavior is preserved (neither `token_missing` nor `token_missing_config` calls `limiter?.recordFailure`), but the rationale has been lost in the refactor. Future maintainers may not understand why this asymmetry is intentional and could accidentally add a `recordFailure` call for missing-credential cases. Worth adding the comment back to `authorizeTokenAuth`.
```suggestion
if (!params.connectToken) {
// Don't burn rate-limit slots for missing credentials — the client
// simply hasn't provided a token yet (e.g. bare browser open).
// Only actual *wrong* credentials should count as failures.
return { ok: false, reason: "token_missing" };
}
```
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "Merge branch 'main' into vincentkoc-code..." | Re-trigger Greptile |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3786c202a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Was waiting for this functionality 💯 |
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
🔒 Aisle Security AnalysisWe found 1 potential security issue(s) in this PR:
Vulnerabilities1. 🟡 DNS rebinding / Host-header bypass via weakened local-direct detection
Description
This creates a DNS rebinding risk:
Vulnerable code: const hasForwarded = Boolean(
req.headers?.forwarded ||
req.headers?.["x-forwarded-for"] ||
req.headers?.["x-forwarded-proto"] ||
req.headers?.["x-real-ip"] ||
req.headers?.["x-forwarded-host"],
);
if (!hasForwarded) {
return isLoopbackAddress(req.socket?.remoteAddress);
}Because browsers do not normally set these forwarded headers, a rebinding request to RecommendationReinstate a strict For example: import { isLocalishHost, isLoopbackAddress } from "./net.js";
export function isLocalDirectRequest(req?: IncomingMessage): boolean {
if (!req) return false;
const hasForwarded = Boolean(
req.headers?.forwarded ||
req.headers?.["x-forwarded-for"] ||
req.headers?.["x-forwarded-proto"] ||
req.headers?.["x-real-ip"] ||
req.headers?.["x-forwarded-host"],
);
if (hasForwarded) return false;
const host = typeof req.headers?.host === "string" ? req.headers.host : "";
if (!isLocalishHost(host)) return false;
return isLoopbackAddress(req.socket?.remoteAddress);
}Additionally, consider requiring an unguessable local-only token even for readiness/details endpoints, or validating Analyzed PR: #54536 at commit Last updated on: 2026-03-25T16:57:26Z |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 07a5e809b5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6166069ba3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!hasForwarded) { | ||
| return isLoopbackAddress(req.socket?.remoteAddress); | ||
| } |
There was a problem hiding this comment.
Reinstate strict local-direct classification checks
This now classifies any loopback socket without forwarding headers as local, regardless of Host or trusted-proxy/client-IP resolution, so a same-host reverse proxy that does not forward X-Forwarded-* can make external traffic look local. That broadens access in code paths that trust isLocalDirectRequest(...) for local-only behavior (for example readiness detail disclosure in src/gateway/server-http.ts:206-221, local-admin session-kill override in src/gateway/session-kill-http.ts:79-90, and WebSocket local-client policy in src/gateway/server/ws-connection/message-handler.ts:224-245). Previously, non-local Host loopback requests were treated as remote; this regression weakens that boundary.
Useful? React with 👍 / 👎.
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
Hello! Commit: |
|
Oh sorry, that commit is after your PR. What a pity! |
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…openclaw#54536) * fix(auth): improve local request and trusted proxy handling * fix(gateway): require token for local trusted-proxy fallback * docs(changelog): credit trusted-proxy auth fix * Update src/gateway/auth.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * fix(gateway): fail closed on forwarded local detection * docs(gateway): clarify fail-closed local detection * fix(gateway): harden trusted-proxy local fallback * fix(gateway): align trusted-proxy loopback validation * Update CHANGELOG.md --------- Co-authored-by: “zhangning” <zhangning.2025@bytedance.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Summary
trusted-proxymode, but its current branch allows verified loopback requests through withok: trueanduser: "local"before any secret validation.trusted-proxyinto a localhost auth bypass instead of a local token fallback, which weakens the operator boundary for same-host processes.trusted-proxyauth.trusted-proxybehavior, allowlist enforcement, and same-host reverse proxy header validation remain unchanged.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Root Cause / Regression History (if applicable)
trusted-proxymode short-circuited to a synthetictrusted-proxysuccess result before proxy validation or token validation.git blame, prior PR, issue, or refactor if known): Follow-up to Enhance auth logic for trusted-proxy mode #45264.Regression Test Plan (if applicable)
src/gateway/auth.test.tstrusted-proxylocal-direct requests require a valid token unless they are real proxied requests with identity headers.authorizeGatewayConnect(...).User-visible / Behavior Changes
trusted-proxymode now work only when they present the configured local token.Security Impact (required)
No)Yes)No)No)No)Yes, explain risk + mitigation:Repro + Verification
Environment
pnpm/ local checkoutn/a{ "gateway": { "auth": { "mode": "trusted-proxy", "token": "<token>", "trustedProxy": { "userHeader": "x-forwarded-user" } } } }Steps
mode: "trusted-proxy"and a configured token.Expected
Actual
Evidence
Human Verification (required)
Review Conversations
Compatibility / Migration
Yes)No)No)Failure Recovery (if this breaks)
src/gateway/auth.ts,src/gateway/auth.test.tstrusted-proxymode failing despite a valid token.Risks and Mitigations