From fc5454d876a8461d32d16f65897539e06d5ee567 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 8 Mar 2021 11:02:22 +0100 Subject: [PATCH] Check the XSRF-TOKEN cookie against the active request during 5.4 upgrade It should not be possible to hit the issue in the real world, but we better play safe here. In my tests I could only reproduce the issue by: 1. Taking a snapshot while logged into the ACP. 2. Starting the upgrade until the new cookies have been set. 3. Aborting the upgrade. 4. Rolling back the snapshot. 5. Trying again. In this case the XSRF-TOKEN cookie is correctly signed and the session cookie matches the actual session ID. However the sessionVariables are outdated due to the rollback. The process will continue with the old SECURITY_TOKEN, failing after the new files from 5.4 are deployed. This issue is fixed by also checking the cookie against the current request and the active session to ensure all the values are correctly in place. Resolves #4052 --- .../update_com.woltlab.wcf_5.4_session_1_cookies.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php index 4bd82f9621..ca558c9795 100644 --- a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php @@ -32,7 +32,17 @@ if (!empty($_COOKIE[COOKIE_PREFIX . "user_session"])) { $hasValidXsrfToken = false; if (!empty($_COOKIE['XSRF-TOKEN'])) { - if (CryptoUtil::validateSignedString($_COOKIE['XSRF-TOKEN'])) { + if ( + // Check that the XSRF-TOKEN cookie is correctly signed. + CryptoUtil::validateSignedString($_COOKIE['XSRF-TOKEN']) + // Check that the current session value matches the cookie value. + && WCF::getSession()->checkSecurityToken($_COOKIE['XSRF-TOKEN']) + // Check that the 't' used for this request matches the cookie value. + && ( + !empty($_REQUEST['t']) + && \hash_equals($_COOKIE['XSRF-TOKEN'], $_REQUEST['t']) + ) + ) { $hasValidXsrfToken = true; } } -- 2.20.1