-
-
Notifications
You must be signed in to change notification settings - Fork 68.9k
[Bug]: Gmail push endpoint embeds authentication token in URL query string #11024
Description
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 |
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
pushEndpointdirectly, - setup
--jsonoutput includes rawhookTokenandpushToken, - 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:238source_code/src/hooks/gmail-setup-utils.ts:250
- Setup flow token source and sink wiring:
source_code/src/hooks/gmail-ops.ts:107source_code/src/hooks/gmail-ops.ts:189source_code/src/hooks/gmail-ops.ts:194source_code/src/hooks/gmail-ops.ts:201
- Additional plaintext leakage:
source_code/src/hooks/gmail-ops.ts:277source_code/src/hooks/gmail-ops.ts:259source_code/src/hooks/gmail-ops.ts:260source_code/src/hooks/gmail-ops.ts:269source_code/src/hooks/gmail.ts:237source_code/src/hooks/gmail.ts:241source_code/src/hooks/gmail-ops.ts:361source_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
- Run Gmail setup with Tailscale endpoint generation (for example
openclaw webhooks gmail setup ... --tailscale funnel). - Observe generated endpoint includes query token:
https://<tailscale-host>/<path>?token=<pushToken>. - Confirm that endpoint is applied to Pub/Sub with
--push-endpoint. - Observe setup/watcher logs for leaked values:
- printed
push endpoint, Starting gog ... --token ... --hook-token ...,- optional
--jsonsummary with raw tokens.
- printed
- Replay authenticated-looking webhook requests using the leaked token.
Recommended Fix
- Remove query-token endpoint construction by default in setup flow.
- Move to authenticated push with OIDC verification end-to-end (subscription auth + receiver verification), and avoid URL-based shared secrets.
- 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.
- 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