Page MenuHomePhabricator

(Old bug fixed in 1.16.5) PHP session data timeout problem
Closed, ResolvedPublic

Description

Author: dnessett

Description:
There is a problem with the utilization of PHP sessions. The data of a timed out PHP session survives and allows logged out users to edit data even when a wiki is setup to only allow logged in users to edit pages. The bug is reproducible in the following way.

+ First, permissions must be set so that anonymous users can only read pages, while logged in users can perform the normal non-sysadmin functions.

On a development machine (NOT a production machine):

+ Log out of the wiki, if you are currently logged in (or have checked the
"remember me" box).

+ Make the following changes to php.ini:

  • session.gc_probability = 100
  • session.gc_divisor = 100
  • session.gc_maxlifetime = 60
  • session.save_path = <some directory writable by httpd>

+ Restart httpd

+ Delete all sessions in the session directory (i.e., session.save_path).
This isn't strictly necessary, but it makes it easier to see how the
session data are manipulated.

+ Access the wiki and login (DO NOT CHECK THE "REMEMBER ME" BOX). Move to
a wiki page that you can edit. A new session file is created and it will
look something like (assuming you logged on as the WikiSysop user):

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|
s:9:"WikiSysop";wsLoginToken|N;

+ Wait 60 seconds or more.

Edit the page by clicking on the edit tab. Make a change and save the
page. You will see the message "Sorry! We could not process your edit due
to a loss of session data. Please try again. If it still does not work,
try logging out and logging back in." The session file will contain:

wsUserID|i:1;wsUserName|s:9:"WikiSysop";

Save the page again. This time it will work. The session data will not
change. Now look at Recent Changes. The edit will show the successful edit
assigned to an IP address not to the user.

This indicates three problems. First, an edit is allowed even though the session has expired. Second, the edit is assigned to an IP address (which, actually, is a direct result of the first problem). Finally, you can continue to edit pages even though you are shown as logged out (the "log in/create account" message is shown at the top of the page).

This bug is discussed in the Mediawiki-l thread "MW seems to get confused when IP address of client machine changes while user is logged in" started on October 10, 11:16 a.m.


Version: 1.16.x
Severity: normal

Details

Reference
bz32122
TitleReferenceAuthorSource BranchDest Branch
add linting and tests to the projectrepos/releng/docpub!3jnucheadd-verificationmain
Customize query in GitLab

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 12:05 AM
bzimport set Reference to bz32122.
bzimport added a subscriber: Unknown Object (MLST).

dnessett wrote:

I am updating this bug, since originally I ran the procedure against a wiki with permissions that allowed anonymous edits. When I ran it against one that limited anonymous users to only read pages and gave logged in users normal non-sysop privileges, the problem didn't occur.

I should mention that the motivation for this line of investigation arose from an intermittent problem on our wikis (which run 1.16.2). Occasionally edit records in Recent Changes would show up with the IP address of the user making the edit. This should never happen on our wikis since, as stated previously, only logged in users should have page edit privileges.

So, while I still believe there is a problem with PHP sessions, I cannot yet reproduce the intermittent problem we observe. However, other improper behavior is reproducible.

For example on both MW 1.16.2 and MW 1.16.5 if you execute the procedure specified earlier in this thread up to the point where an edit is attempted (i.e., log in and wait 60 seconds). Then instead of editing, simply refresh the page, the line at the top of the page still shows the user logged in. However, the session record changes from (before the 60 second timeout):

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|s:9:"WikiSysop";wsLoginToken|N;

to (after the page refresh):

wsUserID|i:1;wsUserName|s:9:"WikiSysop";

It isn't clear why the session file remains after the page refresh, since it should have been cleared by the PHP garbage collector. Furthermore, it isn't clear why the session record contains a wsUserName value of WikiSysop. Since the user is logged out (although this isn't indicated on the browser page), the session record should show an anonymous user.

If you refresh the page again, the logged in/out line is properly displayed as logged out, but the session record has not changed. That is, it still equals:

wsUserID|i:1;wsUserName|s:9:"WikiSysop";

Finally, sometimes when logging in after refreshing the page twice, the following error message is displayed:

"Login error
There seems to be a problem with your login session; this action has been canceled as a precaution against session hijacking. Go back to the previous page, reload that page and then try again."

The session data at this point reads:

wsUserID|i:1;wsUserName|s:9:"WikiSysop";wsLoginToken|s:32:"3bc03a309dd80ff94633dc6b43218309";

This appears to improperly associate the username WikiSysop with an anonymous login token.

dnessett wrote:

This bug is hard to reproduce. It only occurs intermittently on our live wikis and I have not been able to reproduce it reliably on a development wiki. I have, however, found a procedure that produces a problem more frequently, albeit still intermittently, that seems related to the bug. I don't know if all of these steps are required, since I discovered the problem by trial and error.

The context of the following is:

MW 1.16.2
PHP 5.2.4-2ubuntu5.18
Apache/2.2.8 (Ubuntu)

[Note; we run PHP 5.3.5 and Apache/2.2.3 on our live servers and we use CentOS, not Ubuntu]

The relevant LocalSetings.php data are:

Implicit group for all visitors

$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['move'] = false;
$wgGroupPermissions['*']['createpage'] = false;
$wgGroupPermissions['*']['createtalk'] = false;

Implicit group for all logged-in accounts

$wgGroupPermissions['user']['move'] = true;
$wgGroupPermissions['emailconfirmed']['move'] = true;
$wgGroupPermissions['user']['read'] = true;
$wgGroupPermissions['user']['edit'] = true;
$wgGroupPermissions['user']['createpage'] = true;
$wgGroupPermissions['user']['createtalk'] = true;
$wgGroupPermissions['user']['upload'] = true;
$wgGroupPermissions['user']['reupload'] = true;
$wgGroupPermissions['user']['reupload-shared'] = true;
$wgGroupPermissions['user']['minoredit'] = true;

$wgGroupPermissions['sysop']['move'] = true;
$wgGroupPermissions['sysop']['read'] = true;
$wgGroupPermissions['sysop']['edit'] = true;
$wgGroupPermissions['sysop']['createpage'] = true;
$wgGroupPermissions['sysop']['createtalk'] = true;
$wgGroupPermissions['sysop']['upload'] = true;
$wgGroupPermissions['sysop']['reupload'] = true;
$wgGroupPermissions['sysop']['reupload-shared'] = true;
$wgGroupPermissions['sysop']['minoredit'] = true;
$wgGroupPermissions['sysop']['setstatus'] = true;
$wgGroupPermissions['sysop']['checkuser'] = true;

Given this environment, execute the following procedure (the session data appear for a typical execution after the instruction):

Delete all session files.

Restart httpd.

Click Login link:

wsLoginToken|s:32:"66e7648619b7cb11e9f844efc2463963";

Log in:

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|s:9:"WikiSysop";wsLoginToken|N;

Click edit tab:

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|s:9:"WikiSysop";wsLoginToken|N;wsEditToken|s:32:"4322452852043f4a036a4edf958ffbab";

Make a change to the page, wait at least 60 seconds, then save page:

wsUserID|i:1;wsUserName|s:9:"WikiSysop";

Click Login link again and then the edit tab:

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|s:9:"WikiSysop";wsLoginToken|N;wsEditToken|s:32:"4322452852043f4a036a4edf958ffbab";

Make a change to the page, wait at least 60 seconds, then save page:

Most of the time, the edit fails. but sometimes it succeeds. More rarely it fails to log out the user. In the latter case the session file contains

wsUserID|i:1;wsToken|s:32:"0ff5b9ecf52077fb05cc74731f13ba2b";wsUserName|s:9:"WikiSysop";wsLoginToken|N;wsEditToken|s:32:"4322452852043f4a036a4edf958ffbab";

Notice that wsEditToken is the same as the value for the previous edit. Also, the log in status line on the browser page after the edit continues to show the user logged in. This behavior may continue for a few more edits, but eventually the user is logged out.

I have no explanation why this happens and, as specified above, it only happens intermittently. Also, it is not exactly the same problem as this bug describes, but it seems related to problesm with PHP session management.

dnessett wrote:

So far, I have not been able to reproduce the problem described in comment 4 on 1.16.5. However, since it occurs intermittently, that may change. In the meantime, I am setting the version to 1.16.2.

Did you see in comment 3 where I noted that it mostly looks like expected behavior?

What inconsistencies remain other than the session expiration not matching up with cache invalidation (known issue) and expired sessions being replaced by fresh sessions with provisional ID and username filled in from cookies (known normal behavior)?

dnessett wrote:

(In reply to comment #6)

Did you see in comment 3 where I noted that it mostly looks like expected
behavior?

What inconsistencies remain other than the session expiration not matching up
with cache invalidation (known issue) and expired sessions being replaced by
fresh sessions with provisional ID and username filled in from cookies (known
normal behavior)?

For 1.16.2 intermittently edits are allowed after the timeout session expiration period expires (session.gc_maxlifetime) when the probability of the garbage collector running is 1. This is described in comment 4 and the setup information is in comment 4 and the original description. I have not yet found a way to reproduce these anomalies 100% of the time. I am still working on that. My goal is to find such a procedure, run it on 1.16.2 (where the problem occurs) and then test on 1.16.5 to see if the changes made there correct the problem.

For 1.16.2 intermittently edits are allowed after the timeout session
expiration period expires (session.gc_maxlifetime) when the probability of the
garbage collector running is 1.

1.16.2 doesn't have the session permissions fix that's in 1.16.5, so that's entirely expected...

dnessett wrote:

Per the discussion on Mediawiki-l, (http://www.mail-archive.com/mediawiki-l@lists.wikimedia.org/msg08950.html), I am attempting to document the problem for 1.16.2 and provide a definitive test that shows 1.16.5 solves it. As stated previously, we don't have the manpower to continually track new releases of MW, so we tend to stay on one release for a long time. For example, we stayed on 1.13.2 for 3 years. I would imagine there are other wikis that follow a similar strategy.

So, if someone runs up against the problem described in this bug ticket (for a wiki running 1.16.2), it is useful to let them know that 1.16.5 solves it (if it in fact does - right now this is only a conjecture). They can then either move to 1.16.5 or backport the fix to 1.16.2 (probably not a useful strategy in this case, but in other cases where a bug is fixed in a release more distant than the one the wiki runs, sometimes an attractive option). We backported bug fixes for a couple of years before moving to 1.16.2.

Since I have not yet been able to reproduce the problems I documented in the bug ticket comments in 1.16.5, I have changed the version tag on the ticket to 1.16.2. If I find after testing that 1.16.5 has the same problem, I will update the version. Otherwise, I will leave it as it is.

Fair enough; I'm marking it explicitly as an old bug we believe is fixed in 1.16.5 in the summary so people don't confuse it with new, active bugs.

Somebody may or may not close it out as FIXED or INVALID later.

dnessett wrote:

I was able to confirm that the problem described in comment 4 occurs in 1.16.5. I am updating the version to reflect this.

A symptom of the problem is the session data retains wsEditToken after the page is saved. That is, the session file contains the same value before and after the save page operation. For example:

wsUserID|i:1;wsToken|s:32:"895091d5eb444a89d6e29b679b4ec8ac";wsUserName|s:9:"WikiSysop";wsLoginToken|N;wsEditToken|s:32:"830e02f541f9d7caaf32a8f34d94ab12";

When the problem does not occur, the session file contains state reflecting a logged out session, e.g.,

wsUserID|i:1;wsUserName|s:9:"WikiSysop";

dnessett wrote:

I have also confirmed that 1.16.5 suffers from the problem of logging in and receiving the message:

"Login error
There seems to be a problem with your login session; this action has been
canceled as a precaution against session hijacking. Go back to the previous
page, reload that page and then try again."

It is hard to determine what the context of these problems are since they occur intermittently, but I believe the login that produced this error message occurred after a long wait between logins (which may or may not have anything to do with the problem).

dnessett wrote:

I now have a way to reliably reproduce the problem described in Comment 12.

Login

Immediately log out

Wait more than 60 seconds (this assumes the session.gc settings specified in the original description). Do not change the page, stay on the "Log out" page which states: "You are now logged out. You can continue to use MW_1_16_5 anonymously ..."

Login

The error:

"Login error
There seems to be a problem with your login session; this action has been
canceled as a precaution against session hijacking. Go back to the previous
page, reload that page and then try again."

is displayed.

This is on 1.16.5.

The login problem (comments 12 and 13) are expected.

To avoid someone making you log in with *their* account (bug 23076), we store a token in your session that you must provide when logging in. As your session is expiring, it doesn't match.

The error message you are getting is also quite explicit: "this action has been
canceled as a precaution against session hijacking"

(In reply to comment #11)

A symptom of the problem is the session data retains wsEditToken after the page
is saved. That is, the session file contains the same value before and after
the save page operation.

In other words: the session didn't expire. So the session didn't change but it was saved as an ip?

dnessett wrote:

(In reply to comment #15)

(In reply to comment #11)

A symptom of the problem is the session data retains wsEditToken after the page
is saved. That is, the session file contains the same value before and after
the save page operation.

In other words: the session didn't expire. So the session didn't change but it
was saved as an ip?

No. I still cannot reproduce the problem given in the original description, i.e., edits attributed to IP addresses not users when anonymous editing is disallowed (but evidence of it exists in page histories on our live wikis). The symptom described in comment 11 is, as you state, the session should expire, but it doesn't. I don't understand the use of the session data well enough to determine if retention of the wsEditToken data in the session data after a page save is appropriate or not.

dnessett wrote:

(In reply to comment #14)

The login problem (comments 12 and 13) are expected.

To avoid someone making you log in with *their* account (bug 23076), we store a
token in your session that you must provide when logging in. As your session is
expiring, it doesn't match.

The error message you are getting is also quite explicit: "this action has been
canceled as a precaution against session hijacking"

Well, perhaps I should open an enhancement ticket requesting the elimination of this behavior. When the wiki page initially displays it shows the user as logged out. When logging in it is a bit startling to receive a warning that the login has a problem.

By the way, I updated the version to 1.16.5 since this "problem" occurs in that release. If this is not a bug, then perhaps I should again revert it to 1.16.2, but I also imagine developers will find toggling the version number constantly to be annoying. I haven't modified the title, so it suggests the session problems are old bugs tied to 1.16.2.

dnessett wrote:

This bug ticket is a bit of a mess, for which I take responsibility. To clean it up and clarify separate problems, I will create separate bug tickets for the "Login error" problem and the incorrect login status problem. I am returning the version associated with this ticket to 1.16.2 and will only update it to 1.16.5 if I can find a way to reliably reproduce the problem in the original description and discover it isn't fixed in 1.16.5.

dnessett wrote:

I can now reliably reproduce this bug in 1.16.2. The bug does not occur in 1.16.5.

Do the following (suggested by the discussion in https://bugzilla.wikimedia.org/show_bug.cgi?id=28639).

Access the wiki main page.

Login without checking the "Remember Me" box

Close the browser

Open the browser

Access the wiki main page.

Edit the main page and save the page.

Visit Recent Changes. The edit will appear to come from an IP address contrary to the permissions set in LocalSettings.php (see comment 4).

I am marking this bug as fixed.