GHSA-rf68-8gjr-36q7: Nezha: Host header injection in OAuth2 redirect_uri

GHSA-rf68-8gjr-36q7LOW
Published September 15, 2026
CISO Take

Nezha v2.2.3, a self-hosted server monitoring dashboard, regresses a prior Host header injection fix: when the new optional `dashboard_host` setting is empty, the OAuth2 login flow reflects the attacker-supplied Host header into the `redirect_uri` sent to the identity provider. If the IdP accepts that redirect, a victim's authorization code lands on an attacker-controlled origin, enabling account binding or login takeover. The rated severity is low and there is no EPSS score, KEV listing, public exploit or scanner template, so exploitation likelihood is currently minimal. It does require user interaction and a permissive IdP redirect allowlist, but it affects a realistic default upgrade state, and the package has 504 downstream dependents and 76 other CVEs. No patched release is listed, so set `dashboard_host` explicitly, restrict redirect URIs at the IdP to the exact legitimate callback, and review the fix commit 38824dbc.

Sources:GitHub AdvisoryNVDATLASOpenSSF

What is the risk?

Low overall. The flaw is configuration-dependent (empty `dashboard_host`, OAuth2 enabled, and an IdP that accepts arbitrary or wildcard redirect URIs) and needs a victim to start login through a request carrying a forged Host header. No CVSS vector, EPSS score, KEV listing, public exploit or scanner template exists. Impact is account binding or login takeover on the monitoring dashboard, which can expose infrastructure inventory and control of monitored agents. The package has a middling OpenSSF score of 6.7/10 and a history of 76 other CVEs, so the surrounding security posture warrants attention.

How does the attack unfold?

Initial Access
Attacker lures a victim into starting OAuth2 login through a request carrying a forged Host header.
AML.T0011.003
Exploitation
Nezha reflects the forged Host into the redirect_uri because dashboard_host is empty, and the IdP accepts it.
AML.T0049
Credential Capture
The victim's authorization code is delivered to the attacker-controlled origin and exchanged for tokens.
AML.T0091.000
Impact
Attacker binds to or logs in as the victim, gaining control of the monitoring dashboard and its managed hosts.

What systems are affected?

PackageEcosystemVulnerable RangePatched
Panelgo= 2.2.3No patch
5.8KOpenSSF 6.5514 dependentsPushed 4d ago67% patched~15d to patchFull package profile →

Do you use Panel? You're affected.

How severe is it?

CVSS 3.1
N/A
EPSS
N/A
Exploitation Status
No known exploitation
Sophistication
Moderate

What should I do?

1 step
  1. 1) Set dashboard_host explicitly to the canonical dashboard hostname in the Nezha configuration; this pins the callback URL and removes the vulnerable fallback. 2) At the OAuth2 identity provider, register only the exact legitimate callback URL and disallow wildcard or open redirect URIs. 3) Apply the upstream fix (commit 38824dbc11a63964c5b9296ae4c68e62b34fa04b) or upgrade as soon as a patched release is published; no patched version is listed yet. 4) Have the reverse proxy enforce an allowlist of valid Host headers and reject unknown ones. 5) Detect abuse by reviewing IdP and proxy logs for OAuth2 initiation requests with unexpected Host values or redirect_uri domains, and audit recent OAuth2 account bindings.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Art. 15-Accuracy, robustness and cybersecurity
ISO 42001
A.6.2.6-AI system operation and monitoring
NIST AI RMF
MANAGE 2.3-Respond to and recover from previously unknown risks

Frequently Asked Questions

What is GHSA-rf68-8gjr-36q7?

Nezha v2.2.3, a self-hosted server monitoring dashboard, regresses a prior Host header injection fix: when the new optional `dashboard_host` setting is empty, the OAuth2 login flow reflects the attacker-supplied Host header into the `redirect_uri` sent to the identity provider. If the IdP accepts that redirect, a victim's authorization code lands on an attacker-controlled origin, enabling account binding or login takeover. The rated severity is low and there is no EPSS score, KEV listing, public exploit or scanner template, so exploitation likelihood is currently minimal. It does require user interaction and a permissive IdP redirect allowlist, but it affects a realistic default upgrade state, and the package has 504 downstream dependents and 76 other CVEs. No patched release is listed, so set `dashboard_host` explicitly, restrict redirect URIs at the IdP to the exact legitimate callback, and review the fix commit 38824dbc.

Is GHSA-rf68-8gjr-36q7 actively exploited?

No confirmed active exploitation of GHSA-rf68-8gjr-36q7 has been reported, but organizations should still patch proactively.

How to fix GHSA-rf68-8gjr-36q7?

1) Set `dashboard_host` explicitly to the canonical dashboard hostname in the Nezha configuration; this pins the callback URL and removes the vulnerable fallback. 2) At the OAuth2 identity provider, register only the exact legitimate callback URL and disallow wildcard or open redirect URIs. 3) Apply the upstream fix (commit 38824dbc11a63964c5b9296ae4c68e62b34fa04b) or upgrade as soon as a patched release is published; no patched version is listed yet. 4) Have the reverse proxy enforce an allowlist of valid Host headers and reject unknown ones. 5) Detect abuse by reviewing IdP and proxy logs for OAuth2 initiation requests with unexpected Host values or redirect_uri domains, and audit recent OAuth2 account bindings.

What systems are affected by GHSA-rf68-8gjr-36q7?

This vulnerability affects the following AI/ML architecture patterns: monitoring and operations dashboards, AI infrastructure management, GPU and training cluster monitoring.

What is the CVSS score for GHSA-rf68-8gjr-36q7?

No CVSS score has been assigned yet.

What is the AI security impact?

Affected AI Architectures

monitoring and operations dashboardsAI infrastructure managementGPU and training cluster monitoring

MITRE ATLAS Techniques

AML.T0011.003Malicious Link
AML.T0049Exploit Public-Facing Application
AML.T0091.000Application Access Token

Compliance Controls Affected

EU AI Act: Art. 15
ISO 42001: A.6.2.6
NIST AI RMF: MANAGE 2.3

What are the technical details?

Original Advisory

## Summary Nezha 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. ## Impact An 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. This 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. ## Reproduction On 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: ```http GET /api/v1/oauth2/github?type=1 HTTP/1.1 Host: evil.attacker.test X-Forwarded-Proto: https ``` The generated OAuth2 authorization URL contains: ```text redirect_uri=https%3A%2F%2Fevil.attacker.test%2Fapi%2Fv1%2Foauth2%2Fcallback ``` A minimal route-level unit test demonstrating the issue is: ```go func TestOAuth2Redirect_RegressionWhenDashboardHostEmptyReflectsForgedHost(t *testing.T) { defer setupOAuth2Test(t)() singleton.Conf.InstallHost = "legit-dashboard.example.com" singleton.Conf.DashboardHost = "" singleton.Conf.Oauth2["github"] = &model.Oauth2Config{ ClientID: "client-id", ClientSecret: "client-secret", Endpoint: model.Oauth2Endpoint{AuthURL: "https://idp.example.test/authorize", TokenURL: "https://idp.example.test/token"}, Scopes: []string{"openid"}, } c, _ := newOAuth2Ctx(t) c.Params = gin.Params{{Key: "provider", Value: "github"}} c.Request.Host = "evil.attacker.test" c.Request.URL.RawQuery = "type=1" c.Request.Header.Set("X-Forwarded-Proto", "https") resp, err := oauth2redirect(c) require.NoError(t, err) parsed, err := url.Parse(resp.Redirect) require.NoError(t, err) require.Equal(t, "https://evil.attacker.test/api/v1/oauth2/callback", parsed.Query().Get("redirect_uri")) } ``` The 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. ## Root cause Current `cmd/dashboard/controller/oauth2.go` chooses the request Host unless `DashboardHost` is non-empty: ```go host := c.Request.Host if !singleton.IsReservedDashboardHost(host) && singleton.Conf != nil && singleton.Conf.DashboardHost != "" { host = singleton.Conf.DashboardHost } return scheme + host + "/api/v1/oauth2/callback" ``` The 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. ## Remediation Build the OAuth2 callback URL from a deterministic configured origin. For example: 1. Use `DashboardHost` when it is set. 2. Otherwise fall back to `InstallHost` if it is set, preserving the v2.2.0 invariant for existing deployments. 3. If neither value is set, reject OAuth2 redirect initiation with a configuration error instead of reflecting request Host. Please also add a regression test that `InstallHost` plus empty `DashboardHost` does not reflect a forged Host into `redirect_uri`.

Exploitation Scenario

An attacker finds a Nezha v2.2.3 instance with OAuth2 enabled and `dashboard_host` empty. They get a logged-in administrator to follow a crafted link or request routed through a proxy or hosting trick that sets a forged Host header such as evil.attacker.test on `/api/v1/oauth2/github?type=1`. Nezha builds an authorization URL with redirect_uri pointing to the attacker domain, and because the IdP accepts it, the victim's authorization code is delivered to the attacker. The attacker exchanges the code to bind their identity to the victim's account or log in, gaining control of the dashboard that manages the organization's compute and AI infrastructure hosts.

Weaknesses (CWE)

CWE-601 — URL Redirection to Untrusted Site ('Open Redirect'): The web application accepts a user-controlled input that specifies a link to an external site, and uses that link in a redirect.

  • [Implementation] Assume all input is malicious. Use an "accept known good" input validation strategy, i.e., use a list of acceptable inputs that strictly conform to specifications. Reject any input that does not strictly conform to specifications, or transform it into something that does. When performing input validation, consider all potentially relevant properties, including length, type of input, the full range of acceptable values, missing or extra inputs, syntax, consistency across related fields, and conformance to business rules. As an example of business rule logic, "boat" may be syntactically valid because it only contains alphanumeric characters, but it is not valid if the input is only expected to contain colors such as "red" or "blue." Do not rely exclusively on looking for malicious or malformed inputs. This is likely to miss at least one undesirable input, especially if the code's environment changes. This can give attackers enough room to bypass the intended validation. However, denylis
  • [Architecture and Design] Use an intermediate disclaimer page that provides the user with a clear warning that they are leaving the current site. Implement a long timeout before the redirect occurs, or force the user to click on the link. Be careful to avoid XSS problems (CWE-79) when generating the disclaimer page.

Source: MITRE CWE corpus.

Timeline

Published
September 15, 2026
Last Modified
September 15, 2026
First Seen
September 15, 2026

Related Vulnerabilities