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…
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
- high · 8.5TsDProxy X-Forwarded-For Header Injection Allows IP Spoofing
- critical · 9.1kin-openapi: ValidationHandler Fail-Open Authentication Bypass
- high · 7.5CVE-2026-58419CVE-2026-58419: Gitea Notification API Private Issue Metadata Leak After Access Revocation
- high · 7.5CVE-2026-24451CVE-2026-24451: Gitea Fork Sync Information Disclosure via merge-upstream