From 7640fc5b5e0c56319a48e5e99f65a17f2fb27cc2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 22 Oct 2020 14:47:56 +0200 Subject: [PATCH] Add update instructions for session refactoring --- com.woltlab.wcf/package.xml | 24 +++- ..._com.woltlab.wcf_5.4_session_1_cookies.php | 103 ++++++++++++++++++ ...woltlab.wcf_5.4_session_2_user_session.php | 64 +++++++++++ ...woltlab.wcf_5.4_session_3_drop_virtual.php | 28 +++++ ...ab.wcf_5.4_session_4_clean_acp_session.php | 45 ++++++++ ...update_com.woltlab.wcf_5.4_updateStyle.php | 14 +++ 6 files changed, 276 insertions(+), 2 deletions(-) create mode 100644 wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php create mode 100644 wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_2_user_session.php create mode 100644 wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php create mode 100644 wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php create mode 100644 wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_updateStyle.php diff --git a/com.woltlab.wcf/package.xml b/com.woltlab.wcf/package.xml index bf5cfa3661..3dea4502d4 100644 --- a/com.woltlab.wcf/package.xml +++ b/com.woltlab.wcf/package.xml @@ -51,15 +51,35 @@ + + files_pre.tar + acp/update_com.woltlab.wcf_5.4_checkOwnerGroup.php - + acp/update_com.woltlab.wcf_5.4_session_1_cookies.php + acp/update_com.woltlab.wcf_5.4_session_2_user_session.php + + - acp/update_com.woltlab.wcf_5.4_removeFiles.php + acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php + acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php acp/update_com.woltlab.wcf_5.4_db.php + acp/update_com.woltlab.wcf_5.4_removeFiles.php + + acp/update_com.woltlab.wcf_5.4_updateStyle.php + 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 new file mode 100644 index 0000000000..7bd8faf70e --- /dev/null +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_1_cookies.php @@ -0,0 +1,103 @@ + + * @package WoltLabSuite\Core + */ + +use wcf\system\application\ApplicationHandler; +use wcf\system\form\container\GroupFormElementContainer; +use wcf\system\form\element\LabelFormElement; +use wcf\system\form\FormDocument; +use wcf\system\request\RouteHandler; +use wcf\system\WCF; +use wcf\util\CryptoUtil; +use wcf\util\HeaderUtil; + +// 1) Check whether the cookies are already in place. +$sessionIdOkay = false; +if (!empty($_COOKIE[COOKIE_PREFIX."acp_session"])) { + $cookieValue = CryptoUtil::getValueFromSignedString($_COOKIE[COOKIE_PREFIX."acp_session"]); + if ($cookieValue) { + $sessionID = \bin2hex($cookieValue); + if ($sessionID === WCF::getSession()->sessionID) { + $sessionIdOkay = true; + } + } +} + +$xsrfTokenOkay = false; +if (!empty($_COOKIE['XSRF-TOKEN'])) { + if (CryptoUtil::validateSignedString($_COOKIE['XSRF-TOKEN'])) { + $xsrfTokenOkay = true; + } +} + +if ($sessionIdOkay && $xsrfTokenOkay) { + // The process may continue; + return; +} + +// 2) Set new session cookie. +HeaderUtil::setCookie( + "acp_session", + CryptoUtil::createSignedString( + \hex2bin(WCF::getSession()->sessionID) + ) +); + +// 3) Set new XSRF-TOKEN cookie. +$sameSite = $cookieDomain = ''; +if (ApplicationHandler::getInstance()->isMultiDomainSetup()) { + // We need to specify the cookieDomain in a multi domain set-up, because + // otherwise no cookies are sent to subdomains. + $cookieDomain = HeaderUtil::getCookieDomain(); + $cookieDomain = ($cookieDomain !== null ? '; domain='.$cookieDomain : ''); +} +else { + // SameSite=strict is not supported in a multi domain set-up, because + // it breaks cross-application requests. + $sameSite = '; SameSite=strict'; +} + +do { + $bytes = \bin2hex(\random_bytes(16)); +} +while (strpos(base64_encode($bytes), '+') !== false); +$xsrfToken = CryptoUtil::createSignedString($bytes); +WCF::getSession()->register('__SECURITY_TOKEN', $xsrfToken); +\header('set-cookie: XSRF-TOKEN='.\rawurlencode($xsrfToken).'; path=/'.$cookieDomain.(RouteHandler::secureConnection() ? '; secure' : '').$sameSite, false); + +// 4) Adjust the SECURITY_TOKEN. +$container = new GroupFormElementContainer(); +$container->setLabel('Set Cookies'); // TODO +$container->setDescription('Sets cookies'); + +$label = new LabelFormElement($container); +$label->setLabel('Set Cookies'); +$label->setDescription( +<<(function() { +var oldToken = SECURITY_TOKEN; +SECURITY_TOKEN = encodeURIComponent("$xsrfToken"); +var oldExecute = WCF.ACP.Package.Installation.prototype._executeStep; +WCF.ACP.Package.Installation.prototype._executeStep = function (step, node, additionalData) { + var request = this._proxy._ajaxRequest; + request.setOption('url', request.getOption('url').replace(oldToken, SECURITY_TOKEN)); + + return oldExecute.call(this, step, node, additionalData); +} +})(); + +EOT +); + +$container->appendChild($label); + +$document = new FormDocument("cookies_set"); +$document->appendContainer($container); + +return $document; diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_2_user_session.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_2_user_session.php new file mode 100644 index 0000000000..2c21d25168 --- /dev/null +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_2_user_session.php @@ -0,0 +1,64 @@ + + * @package WoltLabSuite\Core + */ + +$tables = [ + DatabaseTable::create('wcf1_user_session') + ->columns([ + CharDatabaseTableColumn::create('sessionID') + ->length(40) + ->notNull(), + IntDatabaseTableColumn::create('userID') + ->length(10), + NotNullVarchar255DatabaseTableColumn::create('userAgent') + ->defaultValue(''), + VarcharDatabaseTableColumn::create('ipAddress') + ->length(39) + ->defaultValue(''), + NotNullInt10DatabaseTableColumn::create('lastActivityTime') + ->defaultValue(0), + MediumblobDatabaseTableColumn::create('sessionVariables'), + ]) + ->indices([ + DatabaseTableIndex::create() + ->type(DatabaseTableIndex::PRIMARY_TYPE) + ->columns(['sessionID']), + DatabaseTableIndex::create() + ->columns(['userID']), + DatabaseTableIndex::create() + ->columns(['lastActivityTime']), + ]) + ->foreignKeys([ + DatabaseTableForeignKey::create() + ->columns(['userID']) + ->referencedTable('wcf1_user') + ->referencedColumns(['userID']) + ->onDelete('CASCADE') + ]), +]; + +(new DatabaseTableChangeProcessor( +/** @var ScriptPackageInstallationPlugin $this */ + $this->installation->getPackage(), + $tables, + WCF::getDB()->getEditor()) +)->process(); diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php new file mode 100644 index 0000000000..6c6a678e1d --- /dev/null +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_3_drop_virtual.php @@ -0,0 +1,28 @@ + + * @package WoltLabSuite\Core + */ + +$tables = [ + PartialDatabaseTable::create('wcf1_session_virtual') + ->drop(), + PartialDatabaseTable::create('wcf1_acp_session_virtual') + ->drop(), +]; + +(new DatabaseTableChangeProcessor( +/** @var ScriptPackageInstallationPlugin $this */ + $this->installation->getPackage(), + $tables, + WCF::getDB()->getEditor()) +)->process(); diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php new file mode 100644 index 0000000000..99ebb55d0d --- /dev/null +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_session_4_clean_acp_session.php @@ -0,0 +1,45 @@ + + * @package WoltLabSuite\Core + */ + +$tables = [ + PartialDatabaseTable::create('wcf1_acp_session') + ->columns([ + VarcharDatabaseTableColumn::create('requestURI')->drop(), + VarcharDatabaseTableColumn::create('requestMethod')->drop(), + MediumblobDatabaseTableColumn::create('sessionVariables'), + ]) + ->indices([ + DatabaseTableIndex::create() + ->columns(['userID']), + DatabaseTableIndex::create() + ->columns(['lastActivityTime']), + ]), + PartialDatabaseTable::create('wcf1_acp_session_access_log') + ->columns([ + NotNullVarchar255DatabaseTableColumn::create('requestMethod') + ->defaultValue(''), + ]) +]; + +(new DatabaseTableChangeProcessor( +/** @var ScriptPackageInstallationPlugin $this */ + $this->installation->getPackage(), + $tables, + WCF::getDB()->getEditor()) +)->process(); diff --git a/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_updateStyle.php b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_updateStyle.php new file mode 100644 index 0000000000..64c3700f65 --- /dev/null +++ b/wcfsetup/install/files/acp/update_com.woltlab.wcf_5.4_updateStyle.php @@ -0,0 +1,14 @@ + + * @package WoltLabSuite\Core + */ + +StyleUtil::updateStyleFile(); -- 2.20.1