TSDProxy: Internal Auth Token Leaked to Backend Services Enables Management API Takeover
TSDProxy forwards its internal management authentication token to every proxied backend service, letting any backend on the same host replay that token to gain full admin control over TSDProxy's manag
The problem
When `identityHeaders` is enabled (the default), TSDProxy injects the `x-tsdproxy-auth-token` header into every outgoing upstream request. That token is the same secret the management HTTP server uses to trust identity claims.
The leak is unconditional: `WhoisFromContext` returns `ok=true` even for a zero-value `Whois{}`, so the token is set on every request regardless of whether the user authenticated. The management port's `ResolveWhois` function then accepts any `x-tsdproxy-id` value from localhost as long as the token is present, giving the caller a free identity to impersonate.
Proof of concept
A working proof-of-concept for this issue in github.com/almeidapaulopt/tsdproxy, with the exact payload below.
# 1. Capture the token leaked in a backend request (e.g. via a header-reflection endpoint)
TOKEN=$(curl -s http://localhost:3000/debug/headers \
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d['headers'].get('X-Tsdproxy-Auth-Token',''))")
# 2. Replay from localhost to the management port with an arbitrary identity
curl -H "x-tsdproxy-auth-token: $TOKEN" \
-H "x-tsdproxy-id: attacker" \
http://127.0.0.1:8080/api/v1/proxies
# Returns full proxy list with admin accessThe root cause is two cooperating bugs. In `internal/proxymanager/port.go` (lines 123-132), the `ReverseProxy.Rewrite` function sets `HeaderAuthToken` on the outgoing backend request whenever `identityHeaders=true`, using only an `ok` boolean from `WhoisFromContext` that is `true` even for an empty struct.
In `internal/core/admin.go` (lines 160-182), `ResolveWhois` blindly trusts the `x-tsdproxy-id` header from any localhost connection that presents a valid token.
The fix removes `HeaderAuthToken` from all outgoing backend requests entirely, and adds an `user.ID != ""` guard so identity headers are only injected for genuinely authenticated users. This maps to CWE-200 (information exposure) and CWE-287 (improper authentication).
The fix
Upgrade to `1.4.4-0.20260603142855-434819b4421e` or later. The patch removes `x-tsdproxy-auth-token` from all upstream requests and gates identity-header injection on a non-empty user ID. As a temporary workaround, set `identityHeaders: false` in your proxy configuration to stop the token from being forwarded.
Reported by Vishal Shukla (@shukla304 / @therawdev).
Related research
- critical · 9.1CVE-2026-54089CVE-2026-54089: File Browser Authentication Bypass via Proxy Header Forgery
- high · 7.7CVE-2026-53553CVE-2026-53553: Goploy Arbitrary File Read via Path Traversal in /deploy/fileDiff
- high · 7.4CVE-2026-55076CVE-2026-55076: Coder OIDC email_verified Type Coercion Authentication Bypass
- high · 7.4CVE-2026-55075CVE-2026-55075: Coder OIDC Account Takeover via Email Fallback and email_verified Bypass