Skip to content

[Bug]: Gmail push endpoint embeds authentication token in URL query string #11024

@coygeek

Description

@coygeek

CVSS Assessment

Metric Value
Score 8.3 / 10.0
Severity High
Vector CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L

CVSS v3.1 Calculator

Summary

The Gmail setup flow builds Pub/Sub push endpoints as https://...?...token=<secret> and registers that full URL on the subscription. This exposes the shared secret to URL-bearing telemetry surfaces (reverse-proxy logs, access logs, traces, analytics, copy/paste artifacts).

Verification also found additional plaintext token leakage in local/application logging:

  • setup prints pushEndpoint directly,
  • setup --json output includes raw hookToken and pushToken,
  • watcher/setup command logging prints gog ... --token <pushToken> --hook-token <hookToken>.

Affected Code

  • URL token construction: source_code/src/hooks/gmail-setup-utils.ts:315
  • Pub/Sub endpoint registration with full URL:
    • source_code/src/hooks/gmail-setup-utils.ts:238
    • source_code/src/hooks/gmail-setup-utils.ts:250
  • Setup flow token source and sink wiring:
    • source_code/src/hooks/gmail-ops.ts:107
    • source_code/src/hooks/gmail-ops.ts:189
    • source_code/src/hooks/gmail-ops.ts:194
    • source_code/src/hooks/gmail-ops.ts:201
  • Additional plaintext leakage:
    • source_code/src/hooks/gmail-ops.ts:277
    • source_code/src/hooks/gmail-ops.ts:259
    • source_code/src/hooks/gmail-ops.ts:260
    • source_code/src/hooks/gmail-ops.ts:269
    • source_code/src/hooks/gmail.ts:237
    • source_code/src/hooks/gmail.ts:241
    • source_code/src/hooks/gmail-ops.ts:361
    • source_code/src/hooks/gmail-watcher.ts:68
// source_code/src/hooks/gmail-setup-utils.ts
const baseUrl = `https://${dnsName}${pathArg}`;
return params.token ? `${baseUrl}?token=${params.token}` : baseUrl;

// source_code/src/hooks/gmail-setup-utils.ts
await runGcloud([
  "pubsub",
  "subscriptions",
  "update",
  subscription,
  "--project",
  projectId,
  "--push-endpoint",
  pushEndpoint,
]);

Attack Surface

How is this reached?

  • Network (forged push requests after token disclosure)
  • Adjacent Network (same LAN, requires network proximity)
  • Local (CLI/config path that generates and logs endpoint/token values)
  • Physical (requires physical access to machine)

Authentication required?

  • None (unauthenticated/public access)
  • Low (log/telemetry access, CI logs, shared observability, or equivalent)
  • High (admin/privileged user only)

Entry point: runGmailSetup() provisioning path (ensureTailscaleEndpoint() -> ensureSubscription()) plus setup/watcher log emission of sensitive values.

Exploit Conditions

Complexity:

  • Low (once token is obtained, replay is straightforward)
  • High (requires race condition, specific config, or timing)

User interaction:

  • None (automatic, no victim action needed)
  • Required (victim must click, visit, or perform action)

Prerequisites: Attacker can read URL-bearing logs/telemetry or command output that contains the push token (directly or via full endpoint URL).

Impact Assessment

Scope:

  • Unchanged (impact limited to vulnerable component)
  • Changed (can affect other components, escape sandbox)

What can an attacker do?

Impact Type Level Description
Confidentiality High Shared webhook auth secret (pushToken) is exposed in URL/log output.
Integrity High Stolen token can be replayed to forge Gmail push events into ingestion flow.
Availability Low Forged events can create noise and operational disruption.

Steps to Reproduce

  1. Run Gmail setup with Tailscale endpoint generation (for example openclaw webhooks gmail setup ... --tailscale funnel).
  2. Observe generated endpoint includes query token: https://<tailscale-host>/<path>?token=<pushToken>.
  3. Confirm that endpoint is applied to Pub/Sub with --push-endpoint.
  4. Observe setup/watcher logs for leaked values:
    • printed push endpoint,
    • Starting gog ... --token ... --hook-token ...,
    • optional --json summary with raw tokens.
  5. Replay authenticated-looking webhook requests using the leaked token.

Recommended Fix

  1. Remove query-token endpoint construction by default in setup flow.
  2. Move to authenticated push with OIDC verification end-to-end (subscription auth + receiver verification), and avoid URL-based shared secrets.
  3. Eliminate plaintext token logging:
    • do not print endpoint query strings,
    • do not print command args containing secrets,
    • remove raw token fields from setup JSON output or redact them.
  4. If temporary compatibility is required, gate query-token mode behind an explicit insecure flag and mark it deprecated.

References

  • CWE: CWE-598 - Use of GET Request Method With Sensitive Query Strings

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    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