{
    "document": {
        "category": "csaf_base",
        "csaf_version": "2.0",
        "distribution": {
            "tlp": {
                "label": "WHITE"
            }
        },
        "lang": "en",
        "notes": [
            {
                "category": "legal_disclaimer",
                "text": "The Netherlands Cyber Security Center (henceforth: NCSC-NL) maintains this portal to enhance access to its information and vulnerabilities. The use of this information is subject to the following terms and conditions:\n\nThe vulnerabilities disclosed in this portal are gathered by NCSC-NL from a variety of open sources, which the user can retrieve from other platforms. NCSC-NL makes every reasonable effort to ensure that the content of this portal is kept up to date, and that it is accurate and complete. Nevertheless, NCSC-NL cannot entirely rule out the possibility of errors, and therefore cannot give any warranty in respect of its completeness, accuracy or real-time keeping up-to-date. NCSC-NL does not control nor guarantee the accuracy, relevance, timeliness or completeness of information obtained from these external sources. The vulnerabilities disclosed in this portal are intended solely for the convenience of professional parties to take appropriate measures to manage the risks posed to the cybersecurity. No rights can be derived from the information provided therein.\n\nNCSC-NL and the Kingdom of the Netherlands assume no legal liability or responsibility for any damage resulting from either the use or inability of use of the vulnerabilities disclosed in this portal. This includes damage resulting from the inaccuracy of incompleteness of the information contained in it.\nThe information on this page is subject to Dutch law. All disputes related to or arising from the use of this portal regarding the disclosure of vulnerabilities will be submitted to the competent court in The Hague. This choice of means also applies to the court in summary proceedings."
            }
        ],
        "publisher": {
            "category": "coordinator",
            "contact_details": "cert@ncsc.nl",
            "name": "National Cyber Security Centre",
            "namespace": "https://www.ncsc.nl/"
        },
        "title": "CVE-2026-101090",
        "tracking": {
            "current_release_date": "2026-09-30T17:06:44.977792Z",
            "generator": {
                "date": "2026-02-17T15:00:00Z",
                "engine": {
                    "name": "V.E.L.M.A",
                    "version": "1.7"
                }
            },
            "id": "CVE-2026-101090",
            "initial_release_date": "2026-09-27T21:25:45.839729Z",
            "revision_history": [
                {
                    "date": "2026-09-27T21:25:45.839729Z",
                    "number": "1",
                    "summary": "CVE created.| Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-09-27T21:25:48.874169Z",
                    "number": "2",
                    "summary": "NCSC Score created."
                },
                {
                    "date": "2026-09-28T05:27:18.518819Z",
                    "number": "3",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-09-28T07:35:12.936805Z",
                    "number": "4",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-09-28T12:10:46.814854Z",
                    "number": "5",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (2).| References created (4).| CWES updated (1)."
                },
                {
                    "date": "2026-09-28T12:10:53.662455Z",
                    "number": "6",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-09-28T12:12:50.288844Z",
                    "number": "7",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| CVSS created.| Products connected (1).| Product Identifiers created (1).| References created (2).| CWES updated (1)."
                },
                {
                    "date": "2026-09-28T12:41:12.571371Z",
                    "number": "8",
                    "summary": "CVSS created.| CWES created (1).| Products created (1).| References created (2).| Description created for source.| Unknown change."
                },
                {
                    "date": "2026-09-28T12:41:16.108809Z",
                    "number": "9",
                    "summary": "NCSC Score updated."
                },
                {
                    "date": "2026-09-28T13:38:44.189921Z",
                    "number": "10",
                    "summary": "Unknown change."
                },
                {
                    "date": "2026-09-28T18:12:56.330958Z",
                    "number": "11",
                    "summary": "Source created.| CVE status created. (valid)| Description created for source.| References created (2)."
                },
                {
                    "date": "2026-09-29T16:12:56.988961Z",
                    "number": "12",
                    "summary": "EPSS created.| Unknown change."
                },
                {
                    "date": "2026-09-29T16:13:03.052139Z",
                    "number": "13",
                    "summary": "NCSC Score updated."
                }
            ],
            "status": "interim",
            "version": "13"
        }
    },
    "product_tree": {
        "branches": [
            {
                "branches": [
                    {
                        "branches": [
                            {
                                "category": "product_version_range",
                                "name": "vers:semver/2.2.3|<=2.2.3",
                                "product": {
                                    "name": "vers:semver/2.2.3|<=2.2.3",
                                    "product_id": "CSAFPID-9478774"
                                }
                            },
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/2.2.3",
                                "product": {
                                    "name": "vers:unknown/2.2.3",
                                    "product_id": "CSAFPID-9476476",
                                    "product_identification_helper": {
                                        "purl": "pkg:golang/github.com/nezhahq/nezha@2.2.3"
                                    }
                                }
                            },
                            {
                                "category": "product_version_range",
                                "name": "vers:unknown/v2.2.3",
                                "product": {
                                    "name": "vers:unknown/v2.2.3",
                                    "product_id": "CSAFPID-8676597"
                                }
                            }
                        ],
                        "category": "product_name",
                        "name": "nezha"
                    }
                ],
                "category": "vendor",
                "name": "nezhahq"
            }
        ]
    },
    "vulnerabilities": [
        {
            "cve": "CVE-2026-101090",
            "cwe": {
                "id": "CWE-601",
                "name": "URL Redirection to Untrusted Site ('Open Redirect')"
            },
            "notes": [
                {
                    "category": "description",
                    "text": "Nezha: OAuth2 redirect_uri Host header injection regression when dashboard_host is empty in github.com/nezhahq/nezha",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-6486.json?alt=media"
                },
                {
                    "category": "description",
                    "text": "Nezha 2.2.3 contains a Host header injection regression in the OAuth2 redirect endpoint. When the new optional dashboard_host setting is empty, /api/v1/oauth2/{provider} (cmd/dashboard/controller/oauth2.go) reflects the attacker-supplied HTTP Host header into the redirect_uri sent to the identity provider instead of falling back to the configured install_host. An attacker who induces a victim to begin OAuth2 login via a request that reaches Nezha with a forged Host header can cause an attacker-controlled callback URL to be used as the redirect_uri; if the OAuth2 provider accepts it, the victim's authorization code is delivered to the attacker origin, allowing the attacker to complete the OAuth2 login/binding flow and take over the account. This regresses the fix for GHSA-9rc6-8cjv-rcvx and is configuration-dependent (dashboard_host empty). At the time of the advisory no patched version was available.",
                    "title": "cveprojectv5 - https://www.cve.org/CVERecord?id=CVE-2026-101090"
                },
                {
                    "category": "description",
                    "text": "Nezha 2.2.3 contains a Host header injection regression in the OAuth2 redirect endpoint. When the new optional dashboard_host setting is empty, /api/v1/oauth2/{provider} (cmd/dashboard/controller/oauth2.go) reflects the attacker-supplied HTTP Host header into the redirect_uri sent to the identity provider instead of falling back to the configured install_host. An attacker who induces a victim to begin OAuth2 login via a request that reaches Nezha with a forged Host header can cause an attacker-controlled callback URL to be used as the redirect_uri; if the OAuth2 provider accepts it, the victim's authorization code is delivered to the attacker origin, allowing the attacker to complete the OAuth2 login/binding flow and take over the account. This regresses the fix for GHSA-9rc6-8cjv-rcvx and is configuration-dependent (dashboard_host empty). At the time of the advisory no patched version was available.",
                    "title": "nvd - https://nvd.nist.gov/vuln/detail/CVE-2026-101090"
                },
                {
                    "category": "description",
                    "text": "Nezha 2.2.3 contains a Host header injection regression in the OAuth2 redirect endpoint. When the new optional dashboard_host setting is empty, /api/v1/oauth2/{provider} (cmd/dashboard/controller/oauth2.go) reflects the attacker-supplied HTTP Host header into the redirect_uri sent to the identity provider instead of falling back to the configured install_host. An attacker who induces a victim to begin OAuth2 login via a request that reaches Nezha with a forged Host header can cause an attacker-controlled callback URL to be used as the redirect_uri; if the OAuth2 provider accepts it, the victim's authorization code is delivered to the attacker origin, allowing the attacker to complete the OAuth2 login/binding flow and take over the account. This regresses the fix for GHSA-9rc6-8cjv-rcvx and is configuration-dependent (dashboard_host empty). At the time of the advisory no patched version was available.",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/GIT%2FCVE-2026-101090.json?alt=media"
                },
                {
                    "category": "description",
                    "text": "## Summary\n\nNezha v2.2.3 regresses the GHSA-9rc6-8cjv-rcvx host header injection fix for deployments where the new `dashboard_host` setting is empty. In that configuration, `/api/v1/oauth2/{provider}` again reflects the request `Host` header into the OAuth2 `redirect_uri` sent to the identity provider, even if `install_host` is configured.\n\n## Impact\n\nAn attacker who can get a victim to start OAuth2 login through a request that reaches Nezha with a forged `Host` header can make Nezha send an attacker-controlled callback URL as the OAuth2 `redirect_uri`. If the configured OAuth2 provider accepts that redirect URI, the victim's authorization code is sent to the attacker origin. The attacker can then complete the OAuth2 binding or login flow described in GHSA-9rc6.\n\nThis is configuration-dependent, but it affects a realistic upgrade/default state because `dashboard_host` is a new optional field. The original v2.2.0 fix fell back to `install_host`; current v2.2.3 only falls back when `dashboard_host` is non-empty.\n\n## Reproduction\n\nOn current v2.2.3 / master commit `3d74cd9431a48fa89c6489689eac82a872799ea0`, configure OAuth2 and set an existing dashboard host only through `install_host`, leaving `dashboard_host` empty. Then send the OAuth2 redirect request with a forged Host header:\n\n```http\nGET /api/v1/oauth2/github?type=1 HTTP/1.1\nHost: evil.attacker.test\nX-Forwarded-Proto: https\n```\n\nThe generated OAuth2 authorization URL contains:\n\n```text\nredirect_uri=https%3A%2F%2Fevil.attacker.test%2Fapi%2Fv1%2Foauth2%2Fcallback\n```\n\nA minimal route-level unit test demonstrating the issue is:\n\n```go\nfunc TestOAuth2Redirect_RegressionWhenDashboardHostEmptyReflectsForgedHost(t *testing.T) {\n    defer setupOAuth2Test(t)()\n    singleton.Conf.InstallHost = \"legit-dashboard.example.com\"\n    singleton.Conf.DashboardHost = \"\"\n    singleton.Conf.Oauth2[\"github\"] = &model.Oauth2Config{\n        ClientID: \"client-id\",\n        ClientSecret: \"client-secret\",\n        Endpoint: model.Oauth2Endpoint{AuthURL: \"https://idp.example.test/authorize\", TokenURL: \"https://idp.example.test/token\"},\n        Scopes: []string{\"openid\"},\n    }\n\n    c, _ := newOAuth2Ctx(t)\n    c.Params = gin.Params{{Key: \"provider\", Value: \"github\"}}\n    c.Request.Host = \"evil.attacker.test\"\n    c.Request.URL.RawQuery = \"type=1\"\n    c.Request.Header.Set(\"X-Forwarded-Proto\", \"https\")\n\n    resp, err := oauth2redirect(c)\n    require.NoError(t, err)\n\n    parsed, err := url.Parse(resp.Redirect)\n    require.NoError(t, err)\n    require.Equal(t, \"https://evil.attacker.test/api/v1/oauth2/callback\", parsed.Query().Get(\"redirect_uri\"))\n}\n```\n\nThe corresponding control with `DashboardHost = \"panel.example.com\"` pins the same forged request to `https://panel.example.com/api/v1/oauth2/callback`, so the issue is specifically the empty `dashboard_host` fallback.\n\n## Root cause\n\nCurrent `cmd/dashboard/controller/oauth2.go` chooses the request Host unless `DashboardHost` is non-empty:\n\n```go\nhost := c.Request.Host\nif !singleton.IsReservedDashboardHost(host) && singleton.Conf != nil && singleton.Conf.DashboardHost != \"\" {\n    host = singleton.Conf.DashboardHost\n}\nreturn scheme + host + \"/api/v1/oauth2/callback\"\n```\n\nThe v2.2.0 fix used `InstallHost` as the fallback for untrusted request hosts. After `DashboardHost` was introduced, empty `dashboard_host` now disables host pinning and reintroduces the original Host header injection behavior for those deployments.\n\n## Remediation\n\nBuild the OAuth2 callback URL from a deterministic configured origin. For example:\n\n1. Use `DashboardHost` when it is set.\n2. Otherwise fall back to `InstallHost` if it is set, preserving the v2.2.0 invariant for existing deployments.\n3. If neither value is set, reject OAuth2 redirect initiation with a configuration error instead of reflecting request Host.\n\nPlease also add a regression test that `InstallHost` plus empty `DashboardHost` does not reflect a forged Host into `redirect_uri`.",
                    "title": "osv - https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGHSA-rf68-8gjr-36q7.json?alt=media"
                },
                {
                    "category": "other",
                    "text": "0.00358",
                    "title": "EPSS"
                },
                {
                    "category": "other",
                    "text": "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X",
                    "title": "CVSSV4"
                },
                {
                    "category": "other",
                    "text": "9.3",
                    "title": "CVSSV4 base score"
                },
                {
                    "category": "other",
                    "text": "4.4",
                    "title": "NCSC Score"
                },
                {
                    "category": "other",
                    "text": "There is cwe data available from source Nvd, The value of the most recent CVSS (V3) score",
                    "title": "NCSC Score top decreasing factors"
                }
            ],
            "product_status": {
                "known_affected": [
                    "CSAFPID-8676597",
                    "CSAFPID-9476476",
                    "CSAFPID-9478774"
                ]
            },
            "references": [
                {
                    "category": "external",
                    "summary": "Source - nvd",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-101090"
                },
                {
                    "category": "external",
                    "summary": "Source - ncscclear",
                    "url": "https://vulnerabilities.ncsc.nl/manual/CVE-2026-101090"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/GIT%2FCVE-2026-101090.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGHSA-rf68-8gjr-36q7.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Source - cveprojectv5",
                    "url": "https://www.cve.org/CVERecord?id=CVE-2026-101090"
                },
                {
                    "category": "external",
                    "summary": "Source - osv",
                    "url": "https://www.googleapis.com/download/storage/v1/b/osv-vulnerabilities/o/Go%2FGO-2026-6486.json?alt=media"
                },
                {
                    "category": "external",
                    "summary": "Source - first",
                    "url": "https://api.first.org/data/v1/epss"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; nvd; osv",
                    "url": "https://github.com/nezhahq/nezha/security/advisories/GHSA-rf68-8gjr-36q7"
                },
                {
                    "category": "external",
                    "summary": "Reference - cveprojectv5; nvd; osv",
                    "url": "https://www.vulncheck.com/advisories/nezha-through-2.2.3-host-header-injection-via-oauth2-redirect-uri"
                },
                {
                    "category": "external",
                    "summary": "Reference - osv",
                    "url": "https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/101xxx/CVE-2026-101090.json"
                },
                {
                    "category": "external",
                    "summary": "Reference - osv",
                    "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-101090"
                },
                {
                    "category": "external",
                    "summary": "Reference - osv",
                    "url": "https://github.com/nezhahq/nezha/commit/38824dbc11a63964c5b9296ae4c68e62b34fa04b"
                }
            ],
            "scores": [
                {
                    "cvss_v3": {
                        "version": "3.1",
                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
                        "baseScore": 9.8,
                        "baseSeverity": "CRITICAL"
                    },
                    "products": [
                        "CSAFPID-8676597",
                        "CSAFPID-9476476",
                        "CSAFPID-9478774"
                    ]
                }
            ],
            "title": "CVE-2026-101090"
        }
    ]
}