mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-19 14:00:51 +00:00
feat(security): add audit findings for trusted-proxy mode
- Add critical finding when trusted-proxy auth is enabled - Flag missing trustedProxies configuration - Flag missing userHeader configuration - Warn when allowUsers is empty (allows any authenticated user) Part of #1560 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Peter Steinberger
parent
711fb49a98
commit
47de0ce1db
@@ -346,23 +346,64 @@ function collectGatewayConfigFindings(
|
||||
});
|
||||
}
|
||||
|
||||
const chatCompletionsEnabled = cfg.gateway?.http?.endpoints?.chatCompletions?.enabled === true;
|
||||
const responsesEnabled = cfg.gateway?.http?.endpoints?.responses?.enabled === true;
|
||||
if (chatCompletionsEnabled || responsesEnabled) {
|
||||
const enabledEndpoints = [
|
||||
chatCompletionsEnabled ? "/v1/chat/completions" : null,
|
||||
responsesEnabled ? "/v1/responses" : null,
|
||||
].filter((value): value is string => Boolean(value));
|
||||
// Trusted-proxy auth mode findings
|
||||
if (auth.mode === "trusted-proxy") {
|
||||
const trustedProxies = cfg.gateway?.trustedProxies ?? [];
|
||||
const trustedProxyConfig = cfg.gateway?.auth?.trustedProxy;
|
||||
|
||||
findings.push({
|
||||
checkId: "gateway.http.session_key_override_enabled",
|
||||
severity: remotelyExposed ? "warn" : "info",
|
||||
title: "HTTP APIs accept explicit session key override headers",
|
||||
checkId: "gateway.trusted_proxy_auth",
|
||||
severity: "critical",
|
||||
title: "Trusted-proxy auth mode enabled",
|
||||
detail:
|
||||
`${enabledEndpoints.join(", ")} support x-openclaw-session-key. ` +
|
||||
"Any authenticated caller can route requests into arbitrary sessions.",
|
||||
'gateway.auth.mode="trusted-proxy" delegates authentication to a reverse proxy. ' +
|
||||
"Ensure your proxy (Pomerium, Caddy, nginx) handles auth correctly and that gateway.trustedProxies " +
|
||||
"only contains IPs of your actual proxy servers.",
|
||||
remediation:
|
||||
"Treat HTTP API credentials as full-trust, disable unused endpoints, and avoid sharing tokens across tenants.",
|
||||
"Verify: (1) Your proxy terminates TLS and authenticates users. " +
|
||||
"(2) gateway.trustedProxies is restricted to proxy IPs only. " +
|
||||
"(3) Direct access to the Gateway port is blocked by firewall. " +
|
||||
"See /gateway/trusted-proxy-auth for setup guidance.",
|
||||
});
|
||||
|
||||
if (trustedProxies.length === 0) {
|
||||
findings.push({
|
||||
checkId: "gateway.trusted_proxy_no_proxies",
|
||||
severity: "critical",
|
||||
title: "Trusted-proxy auth enabled but no trusted proxies configured",
|
||||
detail:
|
||||
'gateway.auth.mode="trusted-proxy" but gateway.trustedProxies is empty. ' +
|
||||
"All requests will be rejected.",
|
||||
remediation: "Set gateway.trustedProxies to the IP(s) of your reverse proxy.",
|
||||
});
|
||||
}
|
||||
|
||||
if (!trustedProxyConfig?.userHeader) {
|
||||
findings.push({
|
||||
checkId: "gateway.trusted_proxy_no_user_header",
|
||||
severity: "critical",
|
||||
title: "Trusted-proxy auth missing userHeader config",
|
||||
detail:
|
||||
'gateway.auth.mode="trusted-proxy" but gateway.auth.trustedProxy.userHeader is not configured.',
|
||||
remediation:
|
||||
"Set gateway.auth.trustedProxy.userHeader to the header name your proxy uses " +
|
||||
'(e.g., "x-forwarded-user", "x-pomerium-claim-email").',
|
||||
});
|
||||
}
|
||||
|
||||
const allowUsers = trustedProxyConfig?.allowUsers ?? [];
|
||||
if (allowUsers.length === 0) {
|
||||
findings.push({
|
||||
checkId: "gateway.trusted_proxy_no_allowlist",
|
||||
severity: "warn",
|
||||
title: "Trusted-proxy auth allows all authenticated users",
|
||||
detail:
|
||||
"gateway.auth.trustedProxy.allowUsers is empty, so any user authenticated by your proxy can access the Gateway.",
|
||||
remediation:
|
||||
"Consider setting gateway.auth.trustedProxy.allowUsers to restrict access to specific users " +
|
||||
'(e.g., ["nick@example.com"]).',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (bind !== "loopback" && !cfg.gateway?.auth?.rateLimit) {
|
||||
|
||||
Reference in New Issue
Block a user