[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Consolidates Phabricator application cookies, including registration 5 * and session management. 6 * 7 * @task clientid Client ID Cookie 8 * @task next Next URI Cookie 9 */ 10 final class PhabricatorCookies extends Phobject { 11 12 /** 13 * Stores the login username for password authentication. This is just a 14 * display value for convenience, used to prefill the login form. It is not 15 * authoritative. 16 */ 17 const COOKIE_USERNAME = 'phusr'; 18 19 20 /** 21 * Stores the user's current session ID. This is authoritative and establishes 22 * the user's identity. 23 */ 24 const COOKIE_SESSION = 'phsid'; 25 26 27 /** 28 * Stores a secret used during new account registration to prevent an attacker 29 * from tricking a victim into registering an account which is linked to 30 * credentials the attacker controls. 31 */ 32 const COOKIE_REGISTRATION = 'phreg'; 33 34 35 /** 36 * Stores a secret used during OAuth2 handshakes to prevent various attacks 37 * where an attacker hands a victim a URI corresponding to the middle of an 38 * OAuth2 workflow and we might otherwise do something sketchy. Particularly, 39 * this corresponds to the OAuth2 "code". 40 */ 41 const COOKIE_CLIENTID = 'phcid'; 42 43 44 /** 45 * Stores the URI to redirect the user to after login. This allows users to 46 * visit a path like `/feed/`, be prompted to login, and then be redirected 47 * back to `/feed/` after the workflow completes. 48 */ 49 const COOKIE_NEXTURI = 'next_uri'; 50 51 52 /** 53 * Stores a hint that the user should be moved directly into high security 54 * after upgrading a partial login session. This is used during password 55 * recovery to avoid a double-prompt. 56 */ 57 const COOKIE_HISEC = 'jump_to_hisec'; 58 59 60 /* -( Client ID Cookie )--------------------------------------------------- */ 61 62 63 /** 64 * Set the client ID cookie. This is a random cookie used like a CSRF value 65 * during authentication workflows. 66 * 67 * @param AphrontRequest Request to modify. 68 * @return void 69 * @task clientid 70 */ 71 public static function setClientIDCookie(AphrontRequest $request) { 72 73 // NOTE: See T3471 for some discussion. Some browsers and browser extensions 74 // can make duplicate requests, so we overwrite this cookie only if it is 75 // not present in the request. The cookie lifetime is limited by making it 76 // temporary and clearing it when users log out. 77 78 $value = $request->getCookie(self::COOKIE_CLIENTID); 79 if (!strlen($value)) { 80 $request->setTemporaryCookie( 81 self::COOKIE_CLIENTID, 82 Filesystem::readRandomCharacters(16)); 83 } 84 } 85 86 87 /* -( Next URI Cookie )---------------------------------------------------- */ 88 89 90 /** 91 * Set the Next URI cookie. We only write the cookie if it wasn't recently 92 * written, to avoid writing over a real URI with a bunch of "humans.txt" 93 * stuff. See T3793 for discussion. 94 * 95 * @param AphrontRequest Request to write to. 96 * @param string URI to write. 97 * @param bool Write this cookie even if we have a fresh 98 * cookie already. 99 * @return void 100 * 101 * @task next 102 */ 103 public static function setNextURICookie( 104 AphrontRequest $request, 105 $next_uri, 106 $force = false) { 107 108 if (!$force) { 109 $cookie_value = $request->getCookie(self::COOKIE_NEXTURI); 110 list($set_at, $current_uri) = self::parseNextURICookie($cookie_value); 111 112 // If the cookie was set within the last 2 minutes, don't overwrite it. 113 // Primarily, this prevents browser requests for resources which do not 114 // exist (like "humans.txt" and various icons) from overwriting a normal 115 // URI like "/feed/". 116 if ($set_at > (time() - 120)) { 117 return; 118 } 119 } 120 121 $new_value = time().','.$next_uri; 122 $request->setTemporaryCookie(self::COOKIE_NEXTURI, $new_value); 123 } 124 125 126 /** 127 * Read the URI out of the Next URI cookie. 128 * 129 * @param AphrontRequest Request to examine. 130 * @return string|null Next URI cookie's URI value. 131 * 132 * @task next 133 */ 134 public static function getNextURICookie(AphrontRequest $request) { 135 $cookie_value = $request->getCookie(self::COOKIE_NEXTURI); 136 list($set_at, $next_uri) = self::parseNextURICookie($cookie_value); 137 138 return $next_uri; 139 } 140 141 142 /** 143 * Parse a Next URI cookie into its components. 144 * 145 * @param string Raw cookie value. 146 * @return list<string> List of timestamp and URI. 147 * 148 * @task next 149 */ 150 private static function parseNextURICookie($cookie) { 151 // Old cookies look like: /uri 152 // New cookies look like: timestamp,/uri 153 154 if (!strlen($cookie)) { 155 return null; 156 } 157 158 if (strpos($cookie, ',') !== false) { 159 list($timestamp, $uri) = explode(',', $cookie, 2); 160 return array((int)$timestamp, $uri); 161 } 162 163 return array(0, $cookie); 164 } 165 166 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |