Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] for Incorrect HTTP Redirection When sysPass is Behind a Reverse Proxy with SSL Termination #1939

Open
gsaudade99 opened this issue Oct 4, 2024 · 0 comments

Comments

@gsaudade99
Copy link

sysPass Version
syspass/syspass:3.2.11

Describe the bug
When HTTPS is enforced in the sysPass configuration and the application is running behind a reverse proxy (or load balancer), the application fails to recognize forwarded HTTPS requests. This causes sysPass to redirect users to HTTP instead of maintaining the HTTPS connection, leading to a protocol mismatch. The issue arises because the application does not account for the HTTP_X_FORWARDED_PROTO header, which is often set by reverse proxies to indicate the original protocol used.

To Reproduce
Steps to reproduce the behavior:

  1. Deploy sysPass behind a reverse proxy or load balancer that terminates SSL and forwards requests as HTTP while setting the HTTP_X_FORWARDED_PROTO header to 'https'.
  2. Access sysPass via an HTTPS URL (e.g., https://example.com).
  3. Observe that sysPass incorrectly redirects to http:// instead of staying on https://.

Expected behavior
sysPass should detect that the original request was HTTPS, as indicated by the HTTP_X_FORWARDED_PROTO header, and maintain the HTTPS connection without redirecting to HTTP.

Platform (please complete the following information):

  • OS: Rocky Linux 9.4

How to Fix
In sysPass/lib/SP/Util/HttpUtil.php file changed the code to:

<?php
/**
 * sysPass
 *
 * @author    nuxsmin
 * @link      https://syspass.org
 * @copyright 2012-2019, Rubén Domínguez nuxsmin@$syspass.org
 *
 * This file is part of sysPass.
 *
 * sysPass is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * sysPass is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace SP\Util;

use SP\Config\ConfigData;
use SP\Html\Html;
use SP\Http\Request;

/**
 * Class HttpUtil
 *
 * @package SP\Util
 */
final class HttpUtil
{
    /**
     * Comprobar y forzar (si es necesario) la conexión HTTPS
     *
     * @param ConfigData $configData
     * @param Request    $request
     */
    public static function checkHttps(ConfigData $configData, Request $request)
    {
            // Check if the request is forwarded as HTTPS
            $isHttpsForwarded = isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https';

            if ($configData->isHttpsEnabled() && !$request->isHttps() && !$isHttpsForwarded) {
                $serverPort = $request->getServerPort();

                // Only append the port if it's not the default port for HTTPS
                $port = ($serverPort && $serverPort != 80 && $serverPort != 443) ? ':' . $serverPort : '';
                $host = str_replace('http://', 'https://', $request->getHttpHost());

                if (!headers_sent()) {
                    header('Location: ' . $host . $port . $_SERVER['REQUEST_URI']);
                    exit();
                }
            }
    }
     /**
     Comprobar si existen parámetros pasados por POST para enviarlos por GET
     */
    public static function importUrlParamsToGet()
    {
        $params = [];

        foreach ($_REQUEST as $param => $value) {
            $param = Filter::getString($param);

            if (strpos($param, 'g_') !== false) {
                $params[] = substr($param, 2) . '=' . Html::sanitize($value);
            }
        }

        return count($params) > 0 ? '?' . implode('&', $params) : '';
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant