Apologies if I'm doing this wrong. This issue touches on security, but should be near-impossible to exploit, so (as I understand the rules) does not need to be dealt with confidentially. Also, the issue is impossible to replicate, at my level of competence at least.
The situation:
We have two users (out of 90,000): Anne (in Aberdeen), and Bob (in Blantyre).
- Anne logs on to a Drupal system, then leaves her computer alone. Time passes (around 1 day).
- Bob logs on to the same system, then leaves his computer alone. More time passes (around 1 day).
- By this point, Anne' session has gone past its session.gc_maxlifetime.
- Anne comes back to her computer and navigates to a different page on the site. The system creates a new session for Anne, trying to keep her logged in. This is recorded in the log files:
Type user
Date Thursday, March 26, 2015 - 16:25
User anne@...
Location https://www...
Referrer https://www...
Message Session opened for anne@...
Severity notice
Hostname 212.xxx.xxx.xxx
- The session id created by the system just happens, by utter random chance, to match Bob's session id. The database flags an error when Anne' session is updated:
Type php
Date Thursday, March 26, 2015 - 16:25
User anne@...
Location https://www...
Referrer https://www...
Message PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'PDYI8l2m9O1ZaRsKxrnuns8LAEE5BjrWfCPFiy_Aphg-PDYI8l2m9O1ZaRsKxrnu' for key 'PRIMARY': UPDATE {sessions} SET sid=:db_update_placeholder_0, ssid=:db_update_placeholder_1 WHERE (ssid = :db_condition_placeholder_0) ; Array ( [:db_update_placeholder_0] => PDYI8l2m9O1ZaRsKxrnuns8LAEE5BjrWfCPFiy_Aphg [:db_update_placeholder_1] => PDYI8l2m9O1ZaRsKxrnuns8LAEE5BjrWfCPFiy_Aphg [:db_condition_placeholder_0] => wPkgs10RMje7-rRuQawsfoQp3_OtsRtvBqIRdYqKryc ) in drupal_session_regenerate() (line 393 of /var/www/.../public_html/includes/session.inc).
Severity error
Hostname 212.xxx.xxx.xxx
- Regardless of receiving this exception, Anne's session goes forward as normal. However, the "welcome" message at the top of the site now says "Hello Bob", and all details that are accessed using data in the "user" table are Bob's. (Fortunately Anne was very honest and immediately contacted Bob using the mobile number stored in his details, and he contacted us.)
So it would appear that drupal_session_regenerate() assumes that because the odds against the session ID it just created matching one already in the database are so astronomical, there's no point in actually testing to see if there was a clash.
As noted above, I am not competent to test this or to suggest any possible fix, but it's clear that the assumption of uniqueness cannot be made.
Comments
Comment #1
Niall Jackson CreditAttribution: Niall Jackson commentedComment #2
Niall Jackson CreditAttribution: Niall Jackson commentedComment #3
Niall Jackson CreditAttribution: Niall Jackson commentedBumping this as it has happened again. Exactly the same sequence of events as above, but after the first incident we added "Session expire" and tightened up session.gc_maxlifetime, as well as keeping the core up to date. The site is now up to > 500,000 users, and as far as we know it is still a very rare occurrence, but as it allows one user to access all of another user's data, we have to treat it as a critical issue.
Comment #4
Niall Jackson CreditAttribution: Niall Jackson commentedComment #5
oriolroger CreditAttribution: oriolroger commentedHello Niall, I think we're having a very similar problem with two users.
Do you have any news or feedback about if this is a drupal security bug, or is related to some custom module?
In our company we're about to update drupal version, from 7.43 to 7.59, so maybe there has been a fix added for this problem.
Thank you very much.
Comment #7
stephencamilo CreditAttribution: stephencamilo as a volunteer commentedComment #8
hestenetReset issue status.