openclaw - 💡(How to fix) Fix [Bug]: Reusing hooks.token as gateway password collapses hook auth into full operator auth

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Technical Reproduction

  1. On release v2026.5.26 commit 10ad3aa16068baa84a1bd9ac4f7d42ae725cedb7, configure OpenClaw with both hook ingress and Gateway password auth enabled, for example hooks.enabled=true, hooks.token="shared-gateway-password-1234567890", gateway.auth.mode="password", and gateway.auth.password="shared-gateway-password-1234567890".
  2. Start the gateway. Startup succeeds because src/gateway/startup-auth.ts:224-245 only blocks reuse against gateway.auth.token. The current regression test src/gateway/startup-auth.test.ts:604-640 explicitly documents that matching hooks.token and gateway.auth.password is allowed.
  3. Send a hook request with Authorization: Bearer shared-gateway-password-1234567890 (or X-OpenClaw-Token) to a valid hook route. src/gateway/server/hooks-request-handler.ts:205-224 accepts it because hook auth compares only against hooks.token.
  4. Replay the same bearer value to a Gateway HTTP endpoint such as POST /tools/invoke.
  5. src/gateway/http-auth-utils.ts:111-116 passes the bearer value as both token and password, and src/gateway/auth.ts:378-397 accepts it in password mode. The request is then treated as authenticated Gateway operator access on /tools/invoke (src/gateway/tools-invoke-http.ts:45-57).

Fix Action

Fix / Workaround

Impact

If hooks.token is reused as gateway.auth.password, an attacker who knows the hook token can escalate from hook-only ingress into full Gateway operator HTTP access. That enables privileged tool execution and other trusted-operator actions outside the intended hook dispatcher boundary.

Demonstrated Impact

The root cause is secret reuse across two different trust boundaries. Hook ingress is meant to authorize only hook dispatch, but the same shared secret is also accepted as Gateway password auth. Because the HTTP auth layer intentionally maps bearer auth to both token and password candidates, any leaked or shared hook token becomes a valid Gateway operator credential whenever password-mode reuse is configured. Existing controls do not stop the boundary crossing: the startup guard checks only token reuse, hooks accept the reused secret, and Gateway HTTP surfaces intentionally grant trusted-operator semantics after shared-secret auth succeeds.

Code Example

export function assertHooksTokenSeparateFromGatewayAuth(params: {
  cfg: OpenClawConfig;
  auth: ResolvedGatewayAuth;
}): void {
  if (params.cfg.hooks?.enabled !== true) {
    return;
  }
  const hooksToken = normalizeOptionalString(params.cfg.hooks.token) ?? "";
  if (!hooksToken) {
    return;
  }
  const gatewayToken =
    params.auth.mode === "token" ? (normalizeOptionalString(params.auth.token) ?? "") : "";
  if (!gatewayToken) {
    return;
  }
RAW_BUFFERClick to expand / collapse

Severity Assessment

CVSS Assessment

Metricv3.1v4.0
Score10.0 / 10.010.0 / 10.0
SeverityCriticalCritical
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:HCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H
CalculatorCVSS v3.1 CalculatorCVSS v4.0 Calculator

Threat Model Alignment

Classification: security-specific

This crosses OpenClaw's documented auth boundary between hook ingress and Gateway shared-secret operator auth. openclaw/SECURITY.md treats Gateway token/password auth and /tools/invoke as trusted-operator surfaces, while hook requests are separately authenticated with hooks.token. In current code, src/gateway/startup-auth.ts:224-245 rejects hooks.token reuse only when the active Gateway credential is a token, not when the active shared secret is gateway.auth.password or the trusted-proxy local password fallback. src/gateway/server/hooks-request-handler.ts:205-224 accepts that reused value for hook ingress, and src/gateway/http-auth-utils.ts:111-116 replays any bearer secret as both { token, password }, letting the same secret satisfy Gateway password auth. This is not prompt injection, not a shared-gateway multi-tenant claim, and not a trusted-plugin scenario. The claim does not rely on adversarial operators sharing one gateway host/config.

Impact

If hooks.token is reused as gateway.auth.password, an attacker who knows the hook token can escalate from hook-only ingress into full Gateway operator HTTP access. That enables privileged tool execution and other trusted-operator actions outside the intended hook dispatcher boundary.

Affected Component

File: src/gateway/startup-auth.ts:224-245

export function assertHooksTokenSeparateFromGatewayAuth(params: {
  cfg: OpenClawConfig;
  auth: ResolvedGatewayAuth;
}): void {
  if (params.cfg.hooks?.enabled !== true) {
    return;
  }
  const hooksToken = normalizeOptionalString(params.cfg.hooks.token) ?? "";
  if (!hooksToken) {
    return;
  }
  const gatewayToken =
    params.auth.mode === "token" ? (normalizeOptionalString(params.auth.token) ?? "") : "";
  if (!gatewayToken) {
    return;
  }

Technical Reproduction

  1. On release v2026.5.26 commit 10ad3aa16068baa84a1bd9ac4f7d42ae725cedb7, configure OpenClaw with both hook ingress and Gateway password auth enabled, for example hooks.enabled=true, hooks.token="shared-gateway-password-1234567890", gateway.auth.mode="password", and gateway.auth.password="shared-gateway-password-1234567890".
  2. Start the gateway. Startup succeeds because src/gateway/startup-auth.ts:224-245 only blocks reuse against gateway.auth.token. The current regression test src/gateway/startup-auth.test.ts:604-640 explicitly documents that matching hooks.token and gateway.auth.password is allowed.
  3. Send a hook request with Authorization: Bearer shared-gateway-password-1234567890 (or X-OpenClaw-Token) to a valid hook route. src/gateway/server/hooks-request-handler.ts:205-224 accepts it because hook auth compares only against hooks.token.
  4. Replay the same bearer value to a Gateway HTTP endpoint such as POST /tools/invoke.
  5. src/gateway/http-auth-utils.ts:111-116 passes the bearer value as both token and password, and src/gateway/auth.ts:378-397 accepts it in password mode. The request is then treated as authenticated Gateway operator access on /tools/invoke (src/gateway/tools-invoke-http.ts:45-57).

Demonstrated Impact

The root cause is secret reuse across two different trust boundaries. Hook ingress is meant to authorize only hook dispatch, but the same shared secret is also accepted as Gateway password auth. Because the HTTP auth layer intentionally maps bearer auth to both token and password candidates, any leaked or shared hook token becomes a valid Gateway operator credential whenever password-mode reuse is configured. Existing controls do not stop the boundary crossing: the startup guard checks only token reuse, hooks accept the reused secret, and Gateway HTTP surfaces intentionally grant trusted-operator semantics after shared-secret auth succeeds.

Environment

Tested against openclaw/openclaw release v2026.5.26, published at 2026-05-27T11:27:24Z, commit 10ad3aa16068baa84a1bd9ac4f7d42ae725cedb7. Evidence inspected in src/gateway/startup-auth.ts, src/gateway/server/hooks-request-handler.ts, src/gateway/http-auth-utils.ts, src/gateway/auth.ts, and src/gateway/tools-invoke-http.ts, with behavioral confirmation from src/gateway/startup-auth.test.ts:604-640.

Remediation Advice

Reject hooks.token reuse against every active shared-secret Gateway credential, including gateway.auth.password and trusted-proxy local password fallbacks, not just gateway.auth.token. Keep hook ingress secrets and Gateway operator shared secrets mutually exclusive across all auth modes.

<!-- submission-marker:CR-van-hooks-token-reuse-gateway-password-auth -->

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: Reusing hooks.token as gateway password collapses hook auth into full operator auth