I have 443 Session module set to force https for authenticated users. However, the module does this by creating a special LOGGED_IN cookie and then checking for it later:

function _session443_bake_cookie($bake) {
  global $cookie_domain;
  if ($bake) {
    // 0 means session cookie.
    $time = 0;
  }

...

  setcookie(variable_get('session443_cookie_name', 'LOGGED_IN'), TRUE, $time, '/', $cookie_domain, FALSE);
}

The problem is that this logic assume the user logs out when they close the browser:

    // 0 means session cookie.
    $time = 0;

However, Drupal by default will keep a user logged in for 23 days, based on settings.php:

ini_set('session.cookie_lifetime',  2000000);

So when an authenticated user closes and then re-opens their browser, 443 Session module assumes they are logged out but the rest of Drupal will maintain that session for 2,000,000 seconds by default. This leads to strange access denied errors when that user goes to the login page, and just generally presents a logged-out experience for a user that should still be considered logged in / authenticated.

I think the solution is that rather than setting the LOGGED_IN cookie lifetime to 0, it should be set to the same as the rest of Drupal. Here's what Boost module does:

function boost_set_cookie($uid, $expires = NULL) {
  if (!$expires) {
    // Let the old way still work, in case user object was passed
    $uid = is_object($uid) ? $uid->uid : $uid;

    $expires = ini_get('session.cookie_lifetime');
    $expires = (!empty($expires) && is_numeric($expires)) ? BOOST_TIME + (int)$expires : 0;
    setcookie(BOOST_COOKIE, strval($uid), $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1');
  }
  else {
    setcookie(BOOST_COOKIE, '0', $expires, ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure') == '1');
  }

...

And here's what Secure Pages Hijack Prevention module does:

function _securepages_prevent_hijack_cookie() {
  if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
    $tok = drupal_get_token('securepages_prevent_hijack');
    $cookie_params = session_get_cookie_params();
    $lifetime = 0;
    if ($cookie_params['lifetime'] > 0) {
      $lifetime = $_SERVER['REQUEST_TIME'] + $cookie_params['lifetime'];
    }
    setcookie(SECUREPAGES_SESSID, $tok, $lifetime,
    $cookie_params['path'], $cookie_params['domain'], 1);
  }

...

Can we do the same thing in 443 Session?

ref: http://php.net/manual/en/function.setcookie.php
ref: http://www.php.net/manual/en/function.ini-get.php
ref: http://php.net/manual/en/function.session-get-cookie-params.php

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dalin’s picture

@ericbroder this sounds reasonable. Can you roll a patch?

ericbroder’s picture

Thanks for the feedback dalin. Yes I will create a patch.

ericbroder’s picture

Status: Active » Needs review
FileSize
495 bytes

Ok here's a patch based on the method from Secure Pages Hijack Prevention module. Seems to work ok, needs additional review. Cookie lifetime matches the rest of Drupal better, is no longer hard wired to 0. Cookie lifetime can be adjusted in settings.php.