From 1535ab4ef15edc761a02e91e25e28e866716c0b5 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 6 Oct 2016 17:14:45 +0200 Subject: [PATCH] Using fixed cookie path This resolves a lot of issues, including cookie tossing, and on top of it finally allows for 3rd party sites residing above the core to share the cookies. --- .../data/application/Application.class.php | 3 +- .../application/ApplicationAction.class.php | 53 +++---------------- .../PackageInstallationDispatcher.class.php | 6 +-- .../files/lib/util/HeaderUtil.class.php | 2 +- wcfsetup/setup/db/install.sql | 1 - 5 files changed, 11 insertions(+), 54 deletions(-) diff --git a/wcfsetup/install/files/lib/data/application/Application.class.php b/wcfsetup/install/files/lib/data/application/Application.class.php index d3d2d29afc..e512c4c1f4 100644 --- a/wcfsetup/install/files/lib/data/application/Application.class.php +++ b/wcfsetup/install/files/lib/data/application/Application.class.php @@ -20,8 +20,7 @@ use wcf\util\FileUtil; * @property-read integer $packageID id of the package which delivers the application * @property-read string $domainName domain used to access the application (may not contain path components, see `$domainPath`) * @property-read string $domainPath path used to access the application - * @property-read string $cookieDomain domain used to set cookies (corresponds to `domain` cookie property; may not contain path components, see `$cookiePath`) - * @property-read string $cookiePath path of the cookie (corresponds to `path` cookie property) + * @property-read string $cookieDomain domain used to set cookies (corresponds to `domain` cookie property; may not contain path components) * @property-read integer $isTainted is `1` if the application is being uninstalled and thus should not be loaded during uninstallation, otherwise `0` */ class Application extends DatabaseObject { diff --git a/wcfsetup/install/files/lib/data/application/ApplicationAction.class.php b/wcfsetup/install/files/lib/data/application/ApplicationAction.class.php index 1abd3c2119..3349bf6f52 100644 --- a/wcfsetup/install/files/lib/data/application/ApplicationAction.class.php +++ b/wcfsetup/install/files/lib/data/application/ApplicationAction.class.php @@ -33,7 +33,7 @@ class ApplicationAction extends AbstractDatabaseObjectAction { public $applicationEditor; /** - * Assigns a list of applications to a group and computes cookie domain and path. + * Assigns a list of applications to a group and computes cookie domain. */ public function rebuild() { if (empty($this->objects)) { @@ -41,60 +41,23 @@ class ApplicationAction extends AbstractDatabaseObjectAction { } $sql = "UPDATE wcf".WCF_N."_application - SET cookieDomain = ?, - cookiePath = ? + SET cookieDomain = ? WHERE packageID = ?"; $statement = WCF::getDB()->prepareStatement($sql); - // calculate cookie path - $domains = []; + // calculate cookie domain $regex = new Regex(':[0-9]+'); + WCF::getDB()->beginTransaction(); foreach ($this->getObjects() as $application) { $domainName = $application->domainName; if (StringUtil::endsWith($regex->replace($domainName, ''), $application->cookieDomain)) { $domainName = $application->cookieDomain; } - if (!isset($domains[$domainName])) { - $domains[$domainName] = []; - } - - $domains[$domainName][$application->packageID] = explode('/', FileUtil::removeLeadingSlash(FileUtil::removeTrailingSlash($application->domainPath))); - } - - WCF::getDB()->beginTransaction(); - foreach ($domains as $domainName => $data) { - $path = null; - foreach ($data as $domainPath) { - if ($path === null) { - $path = $domainPath; - } - else { - foreach ($path as $i => $part) { - if (!isset($domainPath[$i]) || $domainPath[$i] != $part) { - // remove all following elements including current one - foreach ($path as $j => $innerPart) { - if ($j >= $i) { - unset($path[$j]); - } - } - - // skip to next domain - continue 2; - } - } - } - } - - $path = FileUtil::addLeadingSlash(FileUtil::addTrailingSlash(implode('/', $path))); - - foreach (array_keys($data) as $packageID) { - $statement->execute([ - $domainName, - $path, - $packageID - ]); - } + $statement->execute([ + $domainName, + $application->packageID + ]); } WCF::getDB()->commitTransaction(); diff --git a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php index b5a2b5880a..06c6fe3ee5 100644 --- a/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php +++ b/wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php @@ -403,7 +403,6 @@ class PackageInstallationDispatcher { 'domainName' => $host, 'domainPath' => $path, 'cookieDomain' => $host, - 'cookiePath' => $path, 'packageID' => $package->packageID ]); } @@ -799,10 +798,7 @@ class PackageInstallationDispatcher { // update application path $application = new Application($this->getPackage()->packageID); $applicationEditor = new ApplicationEditor($application); - $applicationEditor->update([ - 'domainPath' => $domainPath, - 'cookiePath' => $domainPath - ]); + $applicationEditor->update(['domainPath' => $domainPath]); // create directory and set permissions @mkdir($packageDir, 0777, true); diff --git a/wcfsetup/install/files/lib/util/HeaderUtil.class.php b/wcfsetup/install/files/lib/util/HeaderUtil.class.php index 9ab8b9aa84..f7b843c9cd 100644 --- a/wcfsetup/install/files/lib/util/HeaderUtil.class.php +++ b/wcfsetup/install/files/lib/util/HeaderUtil.class.php @@ -44,7 +44,7 @@ final class HeaderUtil { $application = ApplicationHandler::getInstance()->getActiveApplication(); $addDomain = (mb_strpos($application->cookieDomain, '.') === false || StringUtil::endsWith($application->cookieDomain, '.lan') || StringUtil::endsWith($application->cookieDomain, '.local')) ? false : true; - @header('Set-Cookie: '.rawurlencode(COOKIE_PREFIX.$name).'='.rawurlencode($value).($expire ? '; expires='.gmdate('D, d-M-Y H:i:s', $expire).' GMT; max-age='.($expire - TIME_NOW) : '').'; path='.$application->cookiePath.($addDomain ? '; domain='.$application->cookieDomain : '').(RouteHandler::secureConnection() ? '; secure' : '').'; HttpOnly', false); + @header('Set-Cookie: '.rawurlencode(COOKIE_PREFIX.$name).'='.rawurlencode($value).($expire ? '; expires='.gmdate('D, d-M-Y H:i:s', $expire).' GMT; max-age='.($expire - TIME_NOW) : '').'; path=/'.($addDomain ? '; domain='.$application->cookieDomain : '').(RouteHandler::secureConnection() ? '; secure' : '').'; HttpOnly', false); } /** diff --git a/wcfsetup/setup/db/install.sql b/wcfsetup/setup/db/install.sql index 8fe0a379e0..750ed92776 100644 --- a/wcfsetup/setup/db/install.sql +++ b/wcfsetup/setup/db/install.sql @@ -149,7 +149,6 @@ CREATE TABLE wcf1_application ( domainName VARCHAR(255) NOT NULL, domainPath VARCHAR(255) NOT NULL DEFAULT '/', cookieDomain VARCHAR(255) NOT NULL, - cookiePath VARCHAR(255) NOT NULL DEFAULT '/', isTainted TINYINT(1) NOT NULL DEFAULT 0 ); -- 2.20.1