F-2026-0003·credential-leak-via-url

API Key Exposed in WebSocket Query Parameters

Fixedpentestbackendapigithub.com/bloom-art/api
TL;DR

WebSocket gateways accepted partner API keys via the `?apiKey=` handshake query string, leaking live credentials into access logs, reverse-proxy logs, and browser history. Public partner integration docs actively recommended the leaking form.

Severity
MEDIUM
Impact
MEDIUM
Likelihood
HIGH
Method
MManual review
CAT.
Complexity
LOW
Exploitability
HIGH
02Section · Description

Description

The PartnerPositionWebSocketGateway accepts API keys via the apiKey query parameter in the WebSocket handshake URL. While the gateway also supports the Authorization header (L89-L94), the query parameter path is checked first and is the primary documented method (L84-L87).

typescript
// partner-position-websocket.gateway.ts L83-L97
private extractApiKey(client: Socket): string | undefined {
const queryApiKey = client.handshake.query.apiKey; // checked first
if (typeof queryApiKey === "string" && queryApiKey.length > 0) {
return queryApiKey; // API key in URL: wss://...?apiKey=dm_live_skey_SECRET
}
const authHeader = client.handshake.headers.authorization;
if (typeof authHeader === "string") {
if (authHeader.startsWith(apiKeyAuthHeaderPrefix)) {
return authHeader.slice(apiKeyAuthHeaderPrefix.length);
}
}
return undefined;
}

Frontend / on-chain mitigation analysis: The frontend controls which authentication method is used. If the partner's frontend exclusively uses the Authorization header (L89-L94), no key appears in URLs. However, the backend actively supports and prioritizes the query parameter method, and partners integrating directly may default to this pattern since many WebSocket client libraries make query params easier than custom headers. The backend should enforce the secure path regardless of frontend behavior.

03Section · Impact

Impact

API key leakage through server logs, proxy logs, and browser history.

04Section · Recommendation

Recommendation

Remove query parameter API key support entirely. Require API keys exclusively via the Authorization header. If query parameter auth is needed, implement a short-lived single-use ticket exchange.

05Section · Resolution

Resolution

Fixed in PR #3685, the query-string carrier was removed entirely; auth payload + Authorization header are now required.

Status
Fixed
F-2026-0003

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx