From be64a81e4d4a9c2636d9f1c0fe7dd302c4f2fce8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:36:33 +0000 Subject: [PATCH 1/3] Initial plan From 500f4f887b37ffe311a3a82b0a558f7e61fddea2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:43:20 +0000 Subject: [PATCH 2/3] Fix open redirect vulnerability in login method Co-authored-by: ljonesfl <1099983+ljonesfl@users.noreply.github.com> --- src/Cms/Controllers/Auth/LoginController.php | 43 +++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Cms/Controllers/Auth/LoginController.php b/src/Cms/Controllers/Auth/LoginController.php index e755a10..65d8bd8 100644 --- a/src/Cms/Controllers/Auth/LoginController.php +++ b/src/Cms/Controllers/Auth/LoginController.php @@ -112,7 +112,10 @@ public function login( array $Parameters ): string $this->_SessionManager->flash( 'success', 'Welcome back!' ); // Redirect to intended URL or dashboard - $RedirectUrl = $_POST['redirect_url'] ?? '/admin/dashboard'; + $requestedRedirect = $_POST['redirect_url'] ?? '/admin/dashboard'; + $RedirectUrl = $this->isValidRedirectUrl( $requestedRedirect ) + ? $requestedRedirect + : '/admin/dashboard'; header( 'Location: ' . $RedirectUrl ); exit; } @@ -130,4 +133,42 @@ public function logout( array $Parameters ): string header( 'Location: /login' ); exit; } + + /** + * Validate if a redirect URL is safe to use. + * Only allows relative URLs (starting with /) to prevent open redirect vulnerabilities. + * + * @param string $url The URL to validate + * @return bool True if the URL is safe, false otherwise + */ + private function isValidRedirectUrl( string $url ): bool + { + // Empty URLs are not valid + if( empty( $url ) ) + { + return false; + } + + // Only allow relative URLs that start with / + if( $url[0] !== '/' ) + { + return false; + } + + // Prevent protocol-relative URLs (//example.com) + if( strlen( $url ) > 1 && $url[1] === '/' ) + { + return false; + } + + // Check for malicious patterns + // Prevent URLs with @ symbol (could be used for phishing: /path@evil.com) + // Prevent URLs with backslashes (could bypass filters: /\evil.com) + if( strpos( $url, '@' ) !== false || strpos( $url, '\\' ) !== false ) + { + return false; + } + + return true; + } } From 919a20914952d020bf667b8dda241748df048d03 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 6 Nov 2025 21:44:49 +0000 Subject: [PATCH 3/3] Improve empty string check for clarity Co-authored-by: ljonesfl <1099983+ljonesfl@users.noreply.github.com> --- src/Cms/Controllers/Auth/LoginController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cms/Controllers/Auth/LoginController.php b/src/Cms/Controllers/Auth/LoginController.php index 65d8bd8..524fde5 100644 --- a/src/Cms/Controllers/Auth/LoginController.php +++ b/src/Cms/Controllers/Auth/LoginController.php @@ -144,7 +144,7 @@ public function logout( array $Parameters ): string private function isValidRedirectUrl( string $url ): bool { // Empty URLs are not valid - if( empty( $url ) ) + if( $url === '' ) { return false; }