Page MenuHomePhabricator

[Panic] Login broken in app?
Closed, ResolvedPublic

Description

Logging in via the app doesn't seem to be possible at the moment. I can log in via desktop, API Sandbox, and iOS app, but not the Android app. OTRS reports are confirming this.

              Analytics  D  LoginFunnel: Sending event, event_action = start, event_source = navigation, event_editSessionToken = null
pedia.page.PageActivity  D  unregisterBus():945: Unregistered bus.
IInputConnectionWrapper  W  getSelectedText on inactive InputConnection
                         W  requestCursorAnchorInfo on inactive InputConnection
                         W  getTextBeforeCursor on inactive InputConnection
                         W  getTextBeforeCursor on inactive InputConnection
              Analytics  D  LoginFunnel: Sending event, event_action = error, event_errorText = NeedToken
              Wikipedia  D  Login failed with result NeedToken

Related Objects

Event Timeline

Dbrant raised the priority of this task from to Unbreak Now!.
Dbrant updated the task description. (Show Details)
Dbrant moved this task to Current Sprint on the Wikipedia-Android-App-Backlog board.

I'm about 95% sure I logged in today from the app. I was working on Gather / Watchlist functionality and had to be logged in for it to work. This is a recent issue.

Can you provide a log of the requests and responses, with POST body and HTTP headers (or at least cookies)?

The endpoint we're hitting is https://en.m.wikipedia.org/w/api.php. The body gets written to a stream that I'm trying to dump out in the format it's actually sent in. The intent is:

action=login
format=json
lgname=<username>
lgpassword=<password>
lgtoken=(token from previous request)

requestHeaders={Accept-Encoding=[gzip], Accept-Language=[en], Connection=[Keep-Alive], Content-Type=[application/x-www-form-urlencoded; charset=UTF-8], Host=[en.m.wikipedia.org], User-Agent=[WikipediaApp/2.1.137-dev-2016-01-21 (Android 6.0.1; Phone) Developer Channel], X-WMF-UUID=[63c1e407-47cc-4a51-833e-071a0972c71b]} Cookie=[GeoIP=US:CO:Colorado_Springs:38.85:-104.78:v4, forceHTTPS=true, centralauth_Token=deleted, centralauth_Session=deleted, centralauth_User=deleted, enwikiToken=deleted, enwikiSession=t35gocttofc0mog024iabvimdr3bto34, WMF-Last-Access=22-Jan-2016, forceHTTPS=deleted, CP=H2, enwikiUserID=deleted]

Ok, I tried manually deleting the cookies after the first request. It's still failing. If I've got the code right, here's what that looks like:

requestHeaders={Accept-Encoding=[gzip], Accept-Language=[en], Connection=[Keep-Alive], Content-Type=[application/x-www-form-urlencoded; charset=UTF-8], Host=[en.m.wikipedia.org], User-Agent=[WikipediaApp/2.1.137-dev-2016-01-21 (Android 6.0.1; Phone) Developer Channel], X-WMF-UUID=[63c1e407-47cc-4a51-833e-071a0972c71b]} Cookie=[]

forceHTTPS=true
enwikiSession=t2t2mq9qrf46spdj5ublnjflektih2l
enwikiUserID=deleted
enwikiToken=deleted
centralauth_User=deleted
centralauth_Token=deleted
centralauth_Session=deleted
forceHTTPS=deleted
forceHTTPS=true
forceHTTPS=true
forceHTTPS=deleted
forceHTTPS=true
CP=H2
WMF-Last-Access=22-Jan-2016
GeoIP=US:CO:Colorado_Springs:38.85:-104.78:v4

Er, sorry. Maybe this is slightly more clear:

  1. Make token request via action=login without lgtoken.
  2. Get NeedToken response.
  3. Delete all cookies.
  4. Make token request via action=login with lgtoken.
  5. Still get NeedToken response:
uri=https://en.m.wikipedia.org/w/api.php requestHeaders={Accept-Encoding=[gzip], Accept-Language=[en], Connection=[Keep-Alive], Content-Type=[application/x-www-form-urlencoded; charset=UTF-8], Host=[en.m.wikipedia.org], User-Agent=[WikipediaApp/2.1.137-dev-2016-01-21 (Android 6.0.1; Phone) Developer Channel], X-WMF-UUID=[35da97ae-0680-43dd-9dcc-b04b5d962346]} Cookie=[]

headerKey=p3p domainSpec=en.m.wikipedia.org CP=This is not a P3P policy! See https://en.wikipedia.org/wiki/Special:CentralAutoLogin/P3P for more info.
headerKey=set-cookie domainSpec=en.m.wikipedia.org forceHTTPS=true
headerKey=set-cookie domainSpec=en.m.wikipedia.org enwikiSession=af915cvpo26hjm79cupdvcbbrd279voq
headerKey=set-cookie domainSpec=en.m.wikipedia.org enwikiUserID=deleted
headerKey=set-cookie domainSpec=en.m.wikipedia.org enwikiToken=deleted
headerKey=set-cookie domainSpec=.wikipedia.org centralauth_User=deleted
headerKey=set-cookie domainSpec=.wikipedia.org centralauth_Token=deleted
headerKey=set-cookie domainSpec=.wikipedia.org centralauth_Session=deleted
headerKey=set-cookie domainSpec=en.m.wikipedia.org forceHTTPS=deleted
headerKey=set-cookie domainSpec=.wikipedia.org forceHTTPS=true
headerKey=set-cookie domainSpec=en.m.wikipedia.org forceHTTPS=true
headerKey=set-cookie domainSpec=en.m.wikipedia.org forceHTTPS=deleted
headerKey=set-cookie domainSpec=.wikipedia.org forceHTTPS=true
headerKey=set-cookie domainSpec=en.m.wikipedia.org CP=H2
headerKey=set-cookie domainSpec=en.m.wikipedia.org WMF-Last-Access=22-Jan-2016
headerKey=set-cookie domainSpec=.wikipedia.org GeoIP=US:CO:Colorado_Springs:38.85:-104.78:v4
headerKey=x-analytics domainSpec=en.m.wikipedia.org https=1

Thanks for the logs. Here's what's happening. Before SessionManager was deployed (to Wikipedia's that's Thursday 18:57 UTC per SAL), the API sequence looked like this (lots of irrelevant detail omitted):

  • request with action=login lgname=<username> lgpassword=<password>
  • response with {"login":{"result":"NeedToken","token":<token>}} Set-Cookie: <wiki>Session=<session>
  • request with action=login lgname=<username> lgpassword=<password> lgtoken=<token> Cookie: <wiki>Session=<session>

Now it works like this:

  • request with action=login lgname=<username> lgpassword=<password>
  • response with {"login":{"result":"NeedToken","token":<token>}} Set-Cookie: <wiki>Session=<session> Set-Cookie: <wiki>UserID=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT Set-Cookie: <wiki>Token=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT
  • request with action=login lgname=<username> lgpassword=<password> lgtoken=<token> Cookie: <wiki>Session=<session>

The cookie deletion part is needed since session handling now bails out if there is any inconsistency (such a mismatch between the UserID and Session cookies) so we need to delete any old cookies to avoid that. (This is to follow OWASP best practices, which was requested during security review.)

Per RFC 6265 Set-Cookie: <name>=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT should cause the user agent to delete the cookie (not send back anything by that name). Apparently the HTTP library used by the app gets this wrong, sends back the cookie with value deleted, which triggers the aforementioned security check, the server discards the session due to conflicting data between the various cookies and initiates a new session, so the login token does not match and the server sets and sends back a new token. (Arguably BadToken would be a less confusing response here than NeedToken, but that behavior is not new.)

See T124252#1954611 for a suggested workaround.

Checked with 2.1.137-alpha-2016-01-22 on Nexus 5 (Android 5.1.1) - a user can successfully login.

Tgr lowered the priority of this task from Unbreak Now! to High.Jan 23 2016, 5:38 PM

Downgrading as we rolled back the code.

I was able to edit without logging out/back in and it was attributed to me not IP. (the first preview showed IP but then was username after save and when I went back and made a second preview then ~~~~ showed username that time) Thanks!

I tried login on testwiki and it seemed to work. If I understand correctly, the app was updated, and some compatibility hacks were applied on server side too. Please test again tomorrow to be sure (SessionManager is redeployed to group2 wikis on Thursday) but this is probably resolved.

@Tgr, thanks, this appears to be working correctly on my end too.

Dbrant claimed this task.