Просмотр исходного кода

Mitigate some 404 situations (#9435)

* Mitigate some 404 situations
Fix https://github.com/FreshRSS/FreshRSS/issues/9413 (maybe)
See https://www.php.net/function.session-regenerate-id

* Keep error_code in Session as well

* Ensure login_ok is false
Alexandre Alapetite 1 день назад
Родитель
Сommit
f617083328
4 измененных файлов с 14 добавлено и 9 удалено
  1. 4 4
      app/Controllers/errorController.php
  2. 4 2
      app/Models/Auth.php
  3. 2 1
      lib/Minz/Error.php
  4. 4 2
      lib/Minz/Session.php

+ 4 - 4
app/Controllers/errorController.php

@@ -10,12 +10,12 @@ class FreshRSS_error_Controller extends FreshRSS_ActionController {
 	 *
 	 *
 	 * It is called by Minz_Error::error() method.
 	 * It is called by Minz_Error::error() method.
 	 *
 	 *
-	 * Parameters are passed by Minz_Session to have a proper url:
-	 *   - error_code (default: 404)
-	 *   - error_logs (default: [])
+	 * Parameters:
+	 *   - code: error code passed in the URL or Session (default: 404)
+	 *   - error_logs: passed by Session (default: [])
 	 */
 	 */
 	public function indexAction(): void {
 	public function indexAction(): void {
-		$code_int = Minz_Session::paramInt('error_code') ?: 404;
+		$code_int = Minz_Request::paramInt('code') ?: Minz_Session::paramInt('error_code') ?: 404;
 		/** @var array<string> */
 		/** @var array<string> */
 		$error_logs = Minz_Session::paramArray('error_logs');
 		$error_logs = Minz_Session::paramArray('error_logs');
 		Minz_Session::_params([
 		Minz_Session::_params([

+ 4 - 2
app/Models/Auth.php

@@ -35,10 +35,11 @@ class FreshRSS_Auth {
 			return self::$login_ok;
 			return self::$login_ok;
 		}
 		}
 		if (self::accessControl()) {
 		if (self::accessControl()) {
-			// Rotate the PHP session ID on the unauthenticated->authenticated transition
+			// Rotate the PHP session ID on the unauthenticated->authenticated transition.
+			// Keep the old session (not authenticated) to not break concurrent in-flight requests.
 			if (FreshRSS_Context::systemConf()->auth_type !== 'none') {
 			if (FreshRSS_Context::systemConf()->auth_type !== 'none') {
 				try {
 				try {
-					Minz_Session::regenerateID('FreshRSS');
+					Minz_Session::regenerateID('FreshRSS', delete_old_session: false);
 				} catch (RuntimeException $e) {
 				} catch (RuntimeException $e) {
 					Minz_Log::error('Session could not be regenerated during access restoration: ' . $e->getMessage());
 					Minz_Log::error('Session could not be regenerated during access restoration: ' . $e->getMessage());
 				}
 				}
@@ -116,6 +117,7 @@ class FreshRSS_Auth {
 		FreshRSS_Context::initUser();
 		FreshRSS_Context::initUser();
 		if (!FreshRSS_Context::hasUserConf() || !FreshRSS_Context::userConf()->enabled) {
 		if (!FreshRSS_Context::hasUserConf() || !FreshRSS_Context::userConf()->enabled) {
 			self::$login_ok = false;
 			self::$login_ok = false;
+			Minz_Session::_param('loginOk', false);
 			return false;
 			return false;
 		}
 		}
 
 

+ 2 - 1
lib/Minz/Error.php

@@ -29,7 +29,8 @@ class Minz_Error {
 			'error_logs' => $logs,
 			'error_logs' => $logs,
 		]);
 		]);
 
 
-		Minz_Request::forward(['c' => 'error'], $redirect);
+		// Also pass the error code by URL, in case the session is lost (session ID rotation)
+		Minz_Request::forward(['c' => 'error', 'params' => ['code' => $code]], $redirect);
 	}
 	}
 
 
 	/**
 	/**

+ 4 - 2
lib/Minz/Session.php

@@ -212,9 +212,11 @@ class Minz_Session {
 	/**
 	/**
 	 * Regenerate a session id.
 	 * Regenerate a session id.
 	 *
 	 *
+	 * @param bool $delete_old_session `true` to delete the old session file; set to `false` if it is known
+	 * not to contain authenticated data, to avoid breaking concurrent in-flight requests
 	 * @throws RuntimeException if the session could not be regenerated (e.g. unwritable session storage)
 	 * @throws RuntimeException if the session could not be regenerated (e.g. unwritable session storage)
 	 */
 	 */
-	public static function regenerateID(string $name): void {
+	public static function regenerateID(string $name, bool $delete_old_session = true): void {
 		if (self::$volatile) {
 		if (self::$volatile) {
 			return;
 			return;
 		}
 		}
@@ -226,7 +228,7 @@ class Minz_Session {
 		if (session_name($name) === false || !@session_start()) {
 		if (session_name($name) === false || !@session_start()) {
 			throw new RuntimeException("Session {$name} could not be started!");
 			throw new RuntimeException("Session {$name} could not be started!");
 		}
 		}
-		if (!session_regenerate_id(delete_old_session: true)) {
+		if (!session_regenerate_id(delete_old_session: $delete_old_session)) {
 			throw new RuntimeException('Session could not be regenerated!');
 			throw new RuntimeException('Session could not be regenerated!');
 		}
 		}
 		session_write_close();
 		session_write_close();