This is a spin-off of #715108: Make Merge queries more consistent and robust, aimed at discussing how to fix the merge query in _drupal_session_write().

This merge query rely on the behavior of MergeQuery_mysql, which completely ignores the key() and rely on the unique keys of the table to determine INSERT vs. UPDATE. As a consequence, HTTPS is completely broken on PostgreSQL and SQLite, as highlighted by the fact that SessionHttpsTestCase fail :)

Comments

damien tournoud’s picture

Here is what the current merge query in _drupal_session_write() does:

  • Stores those fields: uid, cache, hostname, session, timestamp
  • Based on the presence of a row with key:
    • (sid = SESSION_ID) over HTTP,
    • (sid = SESSION_ID AND ssid = SESSION_ID) over HTTPS if no insecure session cookie is present,
    • (sid = INSECURE_SESSION_ID AND ssid = SESSION_ID) over HTTPS if an insecure session cookie is present

If I understand correctly, what it *should* do is:

  • Stores those fields: uid, cache, hostname, session, timestamp, and:
    • sid = SESSION_ID if over HTTPS if no insecure session cookie is present,
    • sid = INSECURE_SESSION_ID over HTTPS if an insecure session cookie is present
  • Based on the presence of a row with key:
    • (sid = SESSION_ID) over HTTP,
    • (ssid = SESSION_ID) over HTTPS
damien tournoud’s picture

Status: Active » Needs review
StatusFileSize
new1.55 KB

Here is a patch that implements #1. The session tests pass under SQLite now.

chx’s picture

StatusFileSize
new3.96 KB

This patch also passes tests and does

  • (sid = SESSION_ID) over HTTP,
  • (ssid = SESSION_ID) over HTTPS if double session cookies are not in effect,
  • (sid = INSECURE_SESSION_ID AND ssid = SESSION_ID) over HTTPS if double session cookies are in effect

double cookies mean that both a secure session cookie and an insecure session cookie is present and the variable https is on too.

Also it finally allows (sid,ssid) as the primary key. This makes me feel warm and fuzzy.

There can be fun spinoffs from this patch because a) there was never a test for NULL ssid. Surely we need to do that? b) why ->condition does not do the right thing for ->condition('foo', NULL)? Edit: #813540: Comparisons involving NULL must never return true

damien tournoud’s picture

Marked #764810: Secure Session cleanup: fix session regenerate db_update, test for insecure session cookie during session init as a duplicate, some elements from the other issue will have to be carried around here. Please make sure mfb is credited.

Status: Needs review » Needs work

The last submitted patch, session_write_null_galore.patch, failed testing.

damien tournoud’s picture

Status: Needs work » Needs review
StatusFileSize
new9.63 KB

Merged both patches.

The logic in drupal_session_regenerate() is still broken, because the code doesn't correctly distinguish "I'm in HTTPS and the user was logged using a secure cookie" and "I'm in HTTPS and the user was logged using a insecure cookie", because it uses isset(session_id()) for that and this is always true.

chx’s picture

#6: 813492-session-remix.patch queued for re-testing.

rfay’s picture

subscribe

chx’s picture

StatusFileSize
new9.86 KB

MySQL does not allow NULLs in any of the fields of the compound key (boo) but oh well, empty string works too -- it wont be a problem as only (sid,ssid) needs to be unique neither sid nor ssid is mandated to be unique so they do not really need to be NULL.

Damien's problem, I let him either explain better or fix it. I don't get it.

chx’s picture

StatusFileSize
new8.42 KB

Minus debug

Status: Needs review » Needs work

The last submitted patch, 813492-session-remix.patch, failed testing.

chx’s picture

Status: Needs work » Needs review

I found this in my IRC log and while I could not ask Damien permission to post I can't imagine what I would breach by doing this so "what needs to be tested is: put something in the session as HTTP, login as HTTPS, verify that the session has been carried over, get back to the original anonymous cookie, verify that this session is now inactive". I will write that test.

chx’s picture

StatusFileSize
new8.47 KB

Keeping up w HEAD

Status: Needs review » Needs work

The last submitted patch, 813492-session-remix.patch, failed testing.

chx’s picture

Status: Needs work » Needs review
StatusFileSize
new8.32 KB

Now, now.

Anonymous’s picture

StatusFileSize
new9.79 KB

as discussed with chx in #drupal, i've added a check in the test to make sure that the pre-login anonymous cookie has its session invalidated after login.

damien tournoud’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for working on this, Justin.

Great fix, great additional test coverage. I verify that it passes on both MySQL and SQLite, let's get this in.

dries’s picture

Project: Drupal core » HEAD to HEAD
Version: 7.x-dev »
Component: base system » Code

Committed to CVS HEAD. I'm moving this to head to head.

damien tournoud’s picture

Project: HEAD to HEAD » Drupal core
Version: » 7.x-dev
Component: Code » base system
Status: Reviewed & tested by the community » Fixed

Could we please keep core issues in the core queue and open separate issues for HEAD-to-HEAD?

We can use a tag if that's useful for tracking (for example "Schema Update").

c960657’s picture

Status: Fixed » Needs work

Looks like the column descriptions in hook_schema() needs to reflect that (sid, ssid) is now a multi-column primary key. I think we should just omit the "Primary key"/"Unique key" prefix - it is redundant, and the convention is not used elsewhere in core.

      'sid' => array(
        'description' => "Primary key: A session ID. The value is generated by PHP's Session API.",
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'default' => '',
      ),
      'ssid' => array(
        'description' => "Unique key: Secure session ID. The value is generated by PHP's Session API.",
        'type' => 'varchar',
        'length' => 64,
        'not null' => TRUE,
        'default' => '',
      ),
c960657’s picture

BTW, shouldn't we add an index on the ssid column?

chx’s picture

Priority: Normal » Critical

oh dang yes we should!

chx’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new1.13 KB

There is nothing to review here I have merely executed the requests of c960657

webchick’s picture

Status: Reviewed & tested by the community » Needs work

We're going to need to add that index too on whatever update hook adds the ssid column, no?

marcingy’s picture

Status: Needs work » Needs review
StatusFileSize
new1.71 KB

There is actually no update function that creates ssids on existing sites. This version of the patch adds an update function to create ssid column as part of the upgrade process and adds an index.

marcingy’s picture

StatusFileSize
new1.98 KB

After speaks to chx reworking to move the update to update.inc.

catch’s picture

Should be "+ // Add ssid column and index.

Otherwise seems fine, a little disturbing we had this broken for so long.

marcingy’s picture

StatusFileSize
new1.98 KB

Fix typo

chx’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1.98 KB

Sounds a plan. I have removed a stray newline.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Neither patch fully fixes #28.

marcingy’s picture

Status: Needs work » Needs review
StatusFileSize
new1.98 KB

Remove white space and fix typo (hopefully)

marcingy’s picture

StatusFileSize
new1.98 KB

Fix another docs issue

catch’s picture

Status: Needs review » Reviewed & tested by the community
webchick’s picture

Status: Reviewed & tested by the community » Fixed

Cool, thanks for that!

Committed to HEAD.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

mfb’s picture

I think this patch might have re-opened #575280: Impersonation when an https session exists.? Or is it just me seeing empty string sid and ssid values in my sessions table...

sun’s picture

Issue summary: View changes

#2330279: When operating in mixed mode SSL: data from anonymous non-HTTP session is still available after login discovered a bug that seems to exist since this was committed, causing a different behavior than the expected. Your feedback over there would be appreciated.