@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't try to set anonymous session cookie on CDN/file domain

Summary:
Ref T2380. If an install has a CDN domain configured, but does not list it as an alternate domain (which is standard/correct, but not incredibly common, see T2380), we'll currently try to set anonymous cookies on it. These will correctly fail security rules.

Instead, don't try to set these cookies.

I missed this in testing yesterday because I have a file domain, but I also have it configured as an alternate domain, which allows cookies to be set. Generally, domain management is due for some refactoring.

Test Plan: Set file domain but not as an alternate, logged out, nuked file domain cookies, reloaded page. No error after patch.

Reviewers: btrahan, csilvers

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2380

Differential Revision: https://secure.phabricator.com/D8057

+70 -51
+63 -50
src/aphront/AphrontRequest.php
··· 1 1 <?php 2 2 3 3 /** 4 + * @task data Accessing Request Data 5 + * @task cookie Managing Cookies 4 6 * 5 - * @task data Accessing Request Data 6 - * 7 - * @group aphront 8 7 */ 9 8 final class AphrontRequest { 10 9 ··· 297 296 unset($_COOKIE[$name]); 298 297 } 299 298 300 - final public function setCookie($name, $value, $expire = null) { 299 + /** 300 + * Get the domain which cookies should be set on for this request, or null 301 + * if the request does not correspond to a valid cookie domain. 302 + * 303 + * @return PhutilURI|null Domain URI, or null if no valid domain exists. 304 + * 305 + * @task cookie 306 + */ 307 + private function getCookieDomainURI() { 308 + $host = $this->getHost(); 301 309 302 - $is_secure = false; 303 - 304 - // If a base URI has been configured, ensure cookies are only set on that 305 - // domain. Also, use the URI protocol to control SSL-only cookies. 310 + // If there's no base domain configured, just use whatever the request 311 + // domain is. This makes setup easier, and we'll tell administrators to 312 + // configure a base domain during the setup process. 306 313 $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); 307 - if ($base_uri) { 308 - $alternates = PhabricatorEnv::getEnvConfig('phabricator.allowed-uris'); 309 - $allowed_uris = array_merge( 310 - array($base_uri), 311 - $alternates); 314 + if (!strlen($base_uri)) { 315 + return new PhutilURI('http://'.$host.'/'); 316 + } 312 317 313 - $host = $this->getHost(); 318 + $alternates = PhabricatorEnv::getEnvConfig('phabricator.allowed-uris'); 319 + $allowed_uris = array_merge( 320 + array($base_uri), 321 + $alternates); 314 322 315 - $match = null; 316 - foreach ($allowed_uris as $allowed_uri) { 317 - $uri = new PhutilURI($allowed_uri); 318 - $domain = $uri->getDomain(); 319 - if ($host == $domain) { 320 - $match = $uri; 321 - break; 322 - } 323 + foreach ($allowed_uris as $allowed_uri) { 324 + $uri = new PhutilURI($allowed_uri); 325 + if ($uri->getDomain() == $host) { 326 + return $uri; 323 327 } 328 + } 324 329 325 - if ($match === null) { 326 - if (count($allowed_uris) > 1) { 327 - throw new Exception( 328 - pht( 329 - 'This Phabricator install is configured as "%s", but you are '. 330 - 'accessing it via "%s". Access Phabricator via the primary '. 331 - 'configured domain, or one of the permitted alternate '. 332 - 'domains: %s. Phabricator will not set cookies on other domains '. 333 - 'for security reasons.', 334 - $base_uri, 335 - $host, 336 - implode(', ', $alternates))); 337 - } else { 338 - throw new Exception( 339 - pht( 340 - 'This Phabricator install is configured as "%s", but you are '. 341 - 'accessing it via "%s". Acccess Phabricator via the primary '. 342 - 'configured domain. Phabricator will not set cookies on other '. 343 - 'domains for security reasons.', 344 - $base_uri, 345 - $host)); 346 - } 347 - } 330 + return null; 331 + } 348 332 349 - $base_domain = $match->getDomain(); 350 - $is_secure = ($match->getProtocol() == 'https'); 351 - } else { 352 - $base_uri = new PhutilURI(PhabricatorEnv::getRequestBaseURI()); 353 - $base_domain = $base_uri->getDomain(); 333 + /** 334 + * Determine if security policy rules will allow cookies to be set when 335 + * responding to the request. 336 + * 337 + * @return bool True if setCookie() will succeed. If this method returns 338 + * false, setCookie() will throw. 339 + * 340 + * @task cookie 341 + */ 342 + final public function canSetCookies() { 343 + return (bool)$this->getCookieDomainURI(); 344 + } 345 + 346 + final public function setCookie($name, $value, $expire = null) { 347 + 348 + $is_secure = false; 349 + 350 + $base_domain_uri = $this->getCookieDomainURI(); 351 + if (!$base_domain_uri) { 352 + $configured_as = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); 353 + $accessed_as = $this->getHost(); 354 + 355 + throw new Exception( 356 + pht( 357 + 'This Phabricator install is configured as "%s", but you are '. 358 + 'using the domain name "%s" to access a page which is trying to '. 359 + 'set a cookie. Acccess Phabricator on the configured primary '. 360 + 'domain or a configured alternate domain. Phabricator will not '. 361 + 'set cookies on other domains for security reasons.', 362 + $configured_as, 363 + $accessed_as)); 354 364 } 365 + 366 + $base_domain = $base_domain_uri->getDomain(); 367 + $is_secure = ($base_domain_uri->getProtocol() == 'https'); 355 368 356 369 if ($expire === null) { 357 370 $expire = time() + (60 * 60 * 24 * 365 * 5);
+7 -1
src/applications/base/controller/PhabricatorController.php
··· 50 50 $phsid = $session_engine->establishSession( 51 51 PhabricatorAuthSession::TYPE_WEB, 52 52 null); 53 - $request->setCookie(PhabricatorCookies::COOKIE_SESSION, $phsid); 53 + 54 + // This may be a resource request, in which case we just don't set 55 + // the cookie. 56 + if ($request->canSetCookies()) { 57 + $request->setCookie(PhabricatorCookies::COOKIE_SESSION, $phsid); 58 + } 54 59 } 60 + 55 61 56 62 if (!$user->isLoggedIn()) { 57 63 $user->attachAlternateCSRFString(PhabricatorHash::digest($phsid));