{"id":"GHSA-fq95-v8xc-jm3v","summary":"Fabio - Incomplete fix for CVE-2025-48865: operator-configured trust headers (clientip/tls/requestid) still strippable via the Connection header","details":"**Affected:** github.com/fabiolb/fabio \u003e= 1.6.6 through 1.7.1 and master HEAD (c75f8a6).\n\n### Summary\nThe v1.6.6 fix for CVE-2025-48865 sweeps the client `Connection` header against a hardcoded allowlist `protectHeaders` (proxy/http_headers.go:28-36) containing only the 7 X-Forwarded family headers. Fabio also injects three *operator-configured* server-side trust headers that are NOT in that allowlist, so the original hop-by-hop stripping attack still works against them.\n\n### Details\nThe three unprotected trust headers and where fabio sets them:\n- ClientIPHeader (`proxy.header.clientip`) - http_headers.go:73 `r.Header.Set(cfg.ClientIPHeader, remoteIP)`\n- TLSHeader (`proxy.header.tls`) - http_headers.go:153 `r.Header.Set(cfg.TLSHeader, cfg.TLSHeaderValue)` (TLS connections)\n- RequestID (`proxy.header.requestid`) - http_proxy.go:90 `r.Header.Set(p.Config.RequestID, id())`\n\nOrder of operations in HTTPProxy.ServeHTTP: (1) line 90 sets RequestID; (2) line 175 calls addHeaders, which sweeps the Connection header (keeping the three configured names because they are absent from protectHeaders) and then sets ClientIPHeader/TLSHeader; (3) line 223 runs the Go `httputil.ReverseProxy`, whose `removeHopByHopHeaders` (Go stdlib net/http/httputil/reverseproxy.go) iterates the inbound `Connection` header and `h.Del`s every listed header. The three trust headers fabio just set are therefore deleted before the request reaches the backend.\n\n### PoC\nConfigure `proxy.header.clientip=X-Client-IP`, `proxy.header.requestid=X-Request-ID`. Raw request:\n```\nGET / HTTP/1.1\nHost: foo.com\nConnection: close, X-Client-IP, X-Request-ID\n```\nBackend sees `X-Client-IP: \u003cempty\u003e` and `X-Request-ID: \u003cempty\u003e`. Baseline (`Connection: close`) =\u003e backend sees the real client IP and a request id. The same works for `proxy.header.tls` over TLS (`Connection: close, X-Secure` strips the TLS assertion). Reproduced by the two PASS-ing tests in proxy/poc_cve48865_incomplete_test.go on master HEAD (Go 1.26.4). Control: `X-Forwarded-For` (in protectHeaders) survives, confirming the gap is specific to the configured headers.\n\n### Impact\nWhere a backend trusts these fabio-set headers, an external unauthenticated client can strip/downgrade the trust signal: bypass/poison IP-based ACL or audit that reads the clientip header, downgrade a TLS-terminated request to appear non-TLS to a backend keying off the TLS header, or drop request-id correlation. Scope: deployments that enable the relevant `proxy.header.*` option (all empty by default). Fix: add the configured ClientIPHeader/TLSHeader/RequestID names to the protectHeaders set (or strip their token from the inbound Connection header) inside addHeaders.\n\nParent: CVE-2025-48865 / GHSA-q7p4-7xjv-j3wf (fixed in v1.6.6). This is an incomplete-fix sibling - the same hop-by-hop stripping primitive applies to the operator-configured trust headers the allowlist does not cover.","aliases":["CVE-2026-62987","GO-2026-6566"],"modified":"2026-10-01T20:55:42.177655229Z","published":"2026-09-22T20:34:22Z","database_specific":{"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-09-22T20:34:22Z","nvd_published_at":"2026-09-21T17:17:38Z","cwe_ids":["CWE-290","CWE-348"]},"references":[{"type":"WEB","url":"https://github.com/fabiolb/fabio/security/advisories/GHSA-fq95-v8xc-jm3v"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-62987"},{"type":"WEB","url":"https://github.com/fabiolb/fabio/commit/240526a8004077edad4fb96d25b382bfc3901357"},{"type":"PACKAGE","url":"https://github.com/fabiolb/fabio"},{"type":"WEB","url":"https://github.com/fabiolb/fabio/releases/tag/v1.7.2"}],"affected":[{"package":{"name":"github.com/fabiolb/fabio","ecosystem":"Go","purl":"pkg:golang/github.com/fabiolb/fabio"},"ranges":[{"type":"SEMVER","events":[{"introduced":"1.6.6"},{"fixed":"1.7.2"}]}],"database_specific":{"last_known_affected_version_range":"\u003c= 1.7.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/09/GHSA-fq95-v8xc-jm3v/GHSA-fq95-v8xc-jm3v.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N"}]}