[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/auth/constants/ -> PhabricatorCookies.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1