CVE-2026-62987: Github.com/fabiolb/fabio Operator-configured Trust Headers (clientip/tls/requestid) Still Vulnerability
MODERATECVE-2026-62987 is a MODERATE (CVSS 5.8) operator-configured trust headers (clientip/tls/requestid) still vulnerability (CWE-348: Use of Less Trusted Source) affecting Github.com/fabiolb/fabio libraries in the Go ecosystem. The issue involves operator-configured trust headers (clientip/tls/requestid) still strippable via the connection header. Remediation is available by upgrading affected packages to version 1.7.2.
CVE-2026-62987 at a Glance
Security Impact
CVSS: 5.8
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N).
How to Fix CVE-2026-62987
To remediate this vulnerability, upgrade all affected Github.com/fabiolb/fabio dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade github.com/fabiolb/fabio to 1.7.2
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for github.com/fabiolb/fabio
How to Check if You Are Affected
To determine whether your application is affected by CVE-2026-62987, inspect your project dependencies for Github.com/fabiolb/fabio:
inspect dependencies for github.com/fabiolb/fabio
Analyze the terminal output to locate any version of Github.com/fabiolb/fabio in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.7.2), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-348: Use of Less Trusted Source, where the product has two different sources of the same data or information, but it uses the source that has less support for verification, is less trusted, or is less resistant to attack. In Github.com/fabiolb/fabio, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-62987 Affected Github.com/fabiolb/fabio Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
github.com/fabiolb/fabio
|
Go |
≥ 1.6.6
< 1.7.2
|
1.7.2
|
References
Frequently Asked Questions
What is CVE-2026-62987?
Which Github.com/fabiolb/fabio versions are affected?
What version fixes CVE-2026-62987?
Is github.com/fabiolb/fabio affected?
What is the CVSS score of CVE-2026-62987?
What CWE is associated with CVE-2026-62987?
How can I check Go dependencies for CVE-2026-62987?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-fq95-v8xc-jm3v",
"modified" : "2026-09-22T20:34:22Z",
"published" : "2026-09-22T20:34:22Z",
"aliases" : [ "CVE-2026-62987" ],
"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 >= 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: <empty>` and `X-Request-ID: <empty>`. Baseline (`Connection: close`) => 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.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:L/A:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "Go",
"name" : "github.com/fabiolb/fabio"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "1.6.6"
}, {
"fixed" : "1.7.2"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 1.7.1"
}
} ],
"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"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-290", "CWE-348" ],
"severity" : "MODERATE",
"github_reviewed" : true,
"github_reviewed_at" : "2026-09-22T20:34:22Z",
"nvd_published_at" : "2026-09-21T17:17:38Z"
}
}