From a18e7b6e997b387db7a7aaf91c15f7bb1a947b15 Mon Sep 17 00:00:00 2001 From: Marvin Rensing Date: Fri, 24 Oct 2025 17:46:51 +0200 Subject: [PATCH] Use X-Forwarded-Proto to determine port Using `X-Forwarded-Port` seems to be discouraged as it allows spoofing according to the Caddy proxy devs [0]: "For these X-Forwarded-* headers, by default, the proxy will ignore their values from incoming requests, to prevent spoofing." Instead we should use the X-Forwarded-Proto header to infer the port that the proxy was called at. So https indicates port 443, while http indicates port 80. Fixes #633 [0]: https://caddyserver.com/docs/caddyfile/directives/reverse_proxy?utm_source=chatgpt.com#defaults --- lib/Saml2/Utils.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/Saml2/Utils.php b/lib/Saml2/Utils.php index 6ace614d..41570a39 100644 --- a/lib/Saml2/Utils.php +++ b/lib/Saml2/Utils.php @@ -573,8 +573,8 @@ public static function getSelfPort() $portnumber = null; if (self::$_port) { $portnumber = self::$_port; - } else if (self::getProxyVars() && isset($_SERVER["HTTP_X_FORWARDED_PORT"])) { - $portnumber = $_SERVER["HTTP_X_FORWARDED_PORT"]; + } else if (self::getProxyVars() && self::determinePortFromProxyVars() !== null) { + $portnumber = self::determinePortFromProxyVars(); } else if (isset($_SERVER["SERVER_PORT"])) { $portnumber = $_SERVER["SERVER_PORT"]; } else { @@ -591,6 +591,23 @@ public static function getSelfPort() return $portnumber; } + /** + * @return null|string The port number inferred from the proxy variables (HTTP_X_FORWARDED_...) + */ + private static function determinePortFromProxyVars() + { + if (isset($_SERVER["HTTP_X_FORWARDED_PORT"])) { + return $_SERVER["HTTP_X_FORWARDED_PORT"]; + } else if (isset($_SERVER["HTTP_X_FORWARDED_PROTO"])) { + if ($_SERVER["HTTP_X_FORWARDED_PROTO"] == 'https') { + return '443'; + } elseif ($_SERVER["HTTP_X_FORWARDED_PROTO"] == 'http') { + return '80'; + } + } + return null; + } + /** * Checks if https or http. *