Using fixed cookie path
authorAlexander Ebert <ebert@woltlab.com>
Thu, 6 Oct 2016 15:14:45 +0000 (17:14 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 6 Oct 2016 15:14:45 +0000 (17:14 +0200)
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.

wcfsetup/install/files/lib/data/application/Application.class.php
wcfsetup/install/files/lib/data/application/ApplicationAction.class.php
wcfsetup/install/files/lib/system/package/PackageInstallationDispatcher.class.php
wcfsetup/install/files/lib/util/HeaderUtil.class.php
wcfsetup/setup/db/install.sql

index d3d2d29afcb4fb7c83078a4a81423345c95a8c32..e512c4c1f4a42f1f2b6f95c468ee511718628d88 100644 (file)
@@ -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 {
index 1abd3c21194b2df8bda76355aa2b9a351a9ed9bf..3349bf6f522d1785408a130d1cdb6fb14de64085 100644 (file)
@@ -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();
                
index b5a2b5880a3a8dc55ae574c003363773af1406fc..06c6fe3ee5b79479b15ccaa50c82c63db849f166 100644 (file)
@@ -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);
index 9ab8b9aa8405f477d085d7b592f12bda5cdeee9f..f7b843c9cd340dc734d5d56ec0b97cc6631f9810 100644 (file)
@@ -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);
        }
        
        /**
index 8fe0a379e0b711e959ac211597c2c12845d1d231..750ed927762fe6204b3dab3a4e557767e6a4e807 100644 (file)
@@ -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
 );