Login CSRF
Closed, ResolvedPublic

Description

MediaWiki 1.15.2 and earlier is vulnerable to a cross-site request forgery (CSRF) vulnerability in both its HTML login interface and its API login interface.

Login CSRF is a particularly problematic kind of CSRF when it is combined with user scripting. An attacker can create an account with a user-specific script, then force another user (the "victim") to log in to that account. The prepared user script then takes control of the victim's browser. It can display a login form, apparently on the same domain, which captures the username and password of the victim when they submit the form.

See section 3 of this paper for more discussion of login CSRF:

http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf

To counter this, MediaWiki 1.15.3 will apply the standard defence for CSRF, that is to ask for a secret "token" before it allows a login. In the HTML interface (Special:UserLogin), the token is provided via a hidden form field called wpLoginToken, which the browser will automatically submit.

In the API, the login process becomes:

  1. Submit a request with lgname and lgpassword, in the same way as you did for MediaWiki 1.15.2 and earlier. Save the cookies in the response.
    • An old unpatched server will respond with a response like {"login": {"result": "Success", ... }, assuming JSON format. If this occurs, you are logged in and can stop.
    • A patched 1.15.3 server will respond with {"login": {"result": "NeedToken", "token": ...}. Save the token from this response and proceed to step 2.
  1. Submit a request with the cookies from step 1, and additionally submit the parameter "lgtoken", with the value from the token in step 1.
    • If the session cookie was not submitted correctly, or if the server-side session expired, the server may respond with {"login": {"result": "WrongToken"}}. You can report this as an error to the user, or retry after a few seconds.
    • If everything was OK, the response will be {"login": {"result": "Success", ... } as in MediaWiki 1.15.2.

Version: 1.15.x
Severity: enhancement

bzimport set Reference to bz23076.
tstarling created this task.Via LegacyApr 6 2010, 11:55 PM
Xqt added a comment.Via ConduitApr 15 2010, 11:41 AM

<quote>

  • If the session cookie was not submitted correctly, or if the server-side

session expired, the server may respond with {"login": {"result":
"WrongToken"}}. You can report this as an error to the user, or retry after a
few seconds.
</quote>
If the session cookie was not submitted the server respond again with {"login": {"result": "NeedToken", "token": ...}. This could cause a infinite loop during the login process.

Reedy added a comment.Via ConduitApr 15 2010, 11:43 AM

Should be relatively trivial to fix...

Catrope added a comment.Via ConduitApr 15 2010, 11:44 AM

This is not MediaWiki's problem; sanely-written clients will give up after a number of tries instead of sheepishly going into an infinite loop.

Xqt added a comment.Via ConduitApr 15 2010, 12:02 PM

I agree, it's not a problem to solve infinite loops by client. But mw does not react as described

bzimport added a comment.Via ConduitApr 15 2010, 12:07 PM

Bryan.TongMinh wrote:

Tokens are associated with sessions, so obviously a session cookie is required for it to work at all.

Xqt added a comment.Via ConduitApr 15 2010, 12:29 PM

Step by step:

  1. I submit a request with lgname and lgpassword and save the token from this response
  2. I submit a request with parameter "lgtoken", with the value from the token in step 1. but without the cookies

This means the session cookie was not submitted correctly and I would expect {"result": "WrongToken instead of {"result": "NeedToken",

Catrope added a comment.Via ConduitApr 17 2010, 10:26 AM

(In reply to comment #7)

Step by step:

  1. I submit a request with lgname and lgpassword and save the token from this response
  2. I submit a request with parameter "lgtoken", with the value from the token in step 1. but without the cookies

    This means the session cookie was not submitted correctly and I would expect {"result": "WrongToken instead of {"result": "NeedToken",

From comment #0:

  1. Submit a request with lgname and lgpassword, in the same way as you did for MediaWiki 1.15.2 and earlier. Save the cookies in the response.

[...]

  1. Submit a request WITH THE COOKIES FROM STEP 1, and additionally submit the parameter "lgtoken", with the value from the token in step 1.

(emphasis mine)

The cookie thing was mentioned in the original instructions, seems you missed it.

Platonides added a comment.Via ConduitNov 29 2010, 5:48 PM

Was fixed in r64677

Add Comment

Column Prototype
This is a very early prototype of a persistent column. It is not expected to work yet, and leaving it open will activate other new features which will break things. Press "\" (backslash) on your keyboard to close it now.