Skip to content

[Bug]: gateway.auth.mode=trusted-proxy still accepts local password auth fallback when OPENCLAW_GATEWAY_PASSWORD (or gateway.auth.password) is set #78684

@azvast

Description

@azvast

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

In trusted-proxy mode, gateway auth is expected to be derived from trusted proxy identity headers. Current behavior includes an additional local-direct fallback: when trusted-proxy checks fail on loopback and a password is configured, authorizeGatewayConnect returns password auth success (method: "password"). This creates a second auth path under mode: "trusted-proxy".

Steps to reproduce

  1. Configure gateway auth mode as trusted-proxy and set a password secret as well.
  2. Send a loopback request (same host) that does not satisfy trusted-proxy identity checks.
  3. Include connectAuth.password matching configured password.
  4. Observe successful auth via password fallback.

Expected behavior

When gateway.auth.mode is trusted-proxy, authentication should require trusted-proxy conditions only (or fail closed), unless an explicit separate compatibility mode is enabled.

Actual behavior

Trusted-proxy failures can still authenticate via local-direct password fallback.

OpenClaw version

2026.5.4

Operating system

Ubuntu 24.04 / Windows 11

Install method

npm global

Model

anthropic/claude-sonnet-4.5

Provider / routing chain

anthropic

Additional provider/model setup details

No response

Logs, screenshots, and evidence

:489:src/gateway/auth.ts
  if (auth.mode === "trusted-proxy") {
    ...
    const result = authorizeTrustedProxy({ ... });
    if ("user" in result) {
      ...
      return { ok: true, method: "trusted-proxy", user: result.user };
    }
    if (localDirect && auth.password && connectAuth?.password) {
      ...
      return authorizePasswordAuth({
        authPassword: auth.password,
        connectPassword: connectAuth.password,
        ...
      });
    }
    return { ok: false, reason: result.reason };
  }


:979:src/gateway/auth.test.ts
    it("accepts local-direct password fallback when trusted-proxy auth fails", async () => {
      const limiter = createLimiterSpy();
      const res = await authorizeLocalDirect({
        password: "local-password",
        connectPassword: "local-password",
        rateLimiter: limiter,
      });

      expect(res).toEqual({ ok: true, method: "password" });
    });

Impact and severity

High/critical security footgun on shared-host deployments: trusted-proxy mode can be bypassed to password auth locally when a password is present, which weakens mode isolation and operator expectation that trusted-proxy is the sole auth method.

Additional information

assertGatewayAuthConfigured forbids token coexistence in trusted-proxy mode, but does not forbid password coexistence, which allows this fallback behavior.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingbug:behaviorIncorrect behavior without a crash

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions