Page MenuHomePhabricator

Add way for OAuth apps to only authenticate (no other valid rights)
Closed, ResolvedPublic

Description

Currently, all applications have at least the "basic rights" grant, allowing reading and basic use of the api.

To provide a better user experience for apps that only want to authenticate, and not make authorized calls, OAuth should allow a way to create apps that have no rights.

Additionally, apps that primarily intend to authenticate with the wiki have no way to get access to the authenticating user's email or real name, so having an "authenticate only, and have access to private information" would be nice.

Event Timeline

csteipp created this task.Feb 5 2015, 11:06 PM
csteipp raised the priority of this task from to Medium.
csteipp updated the task description. (Show Details)
csteipp added subscribers: Anomie, Mitar, mmodell and 3 others.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptFeb 5 2015, 11:06 PM
gerritbot added a subscriber: gerritbot.

Change 188938 had a related patch set uploaded (by CSteipp):
[WIP] Add "authn-only" grant

https://gerrit.wikimedia.org/r/188938

Patch-For-Review

Change 188938 had a related patch set uploaded (by CSteipp):
[WIP] Add "authn-only" grant

https://gerrit.wikimedia.org/r/188938

@Anomie, I thought I got further into this, but I guess not. My first approach was to have a radio button to select "Auth only" or Normal, but then I also wanted a way to share email/real name, so I thought this was a little nicer. Feel free to update or start from scratch.

csteipp set Security to None.
Mitar added a comment.Feb 6 2015, 12:35 AM

I think there are two things here. One is authenticate-only permissions. But the other is confusion with Mediawiki OAuth between "authorize" OAuth flow and "authenticate" OAuth flow. In "authorize" user should be prompted with a dialog to confirm the permissions. But in "authenticate" they should not be if they have confirmed the permissions in the past, and the same permissions are being requested. Then user is just redirected through the flow, which makes it feel like they stayed on the original site the whole time.

My initial ticket about this was that Mediawiki OAuth should support "authenticate" flow. With possible more permissions (which were confirmed once in the past). Creating less permissions or even no permissions, but still requiring the dialog defeats the whole idea.

csteipp added a comment.EditedFeb 6 2015, 12:56 AM

I think there are two things here. One is authenticate-only permissions. But the other is confusion with Mediawiki OAuth between "authorize" OAuth flow and "authenticate" OAuth flow. In "authorize" user should be prompted with a dialog to confirm the permissions. But in "authenticate" they should not be if they have confirmed the permissions in the past, and the same permissions are being requested. Then user is just redirected through the flow, which makes it feel like they stayed on the original site the whole time.

Agree, that's why I created a separate task for this :). Once we have permissionless apps, I'm fine allowing permissionless apps to redirect without prompting the user, if the user already has a token established. So user will be prompted the first time they authenticate (also notify them of any private information that's being shared), but subsequent calls (assuming they're logged in) will redirect without interaction.

Mitar added a comment.Feb 6 2015, 1:04 AM

Hm, why only permissionless apps? Other big sites which use OAuth do not make this distinction? Try GitHub, you get asked for permissions the first time, but then you just get redirected. You can also make the token expire after some time and then they have to reauthorize. But to have to authorize every time if they are any permissions is also not good security practice. Security research is showing that the danger is user habituation to the prompt. Then they will stop reading it. And next time an evil developer will change permissions requested, they will just click OK. Habituation to prompts are a big problem. So it is better to make a prompt only when there is something important. Like permissions being asked change. Or token expired. Or there was some other security issue (login happened from strange IP, geoIP is showing multiple connections from multiple continents, etc.).

I would ask you to reconsider. Or make it at least optional, so that user can opt-in or opt-out with a checkbox when confirming the dialog ("Remember my confirmation for 30 days"). But I really think you should not be prompting unnecessary and not even provide such an option.

Change 188938 abandoned by Anomie:
[WIP] Add "authn-only" grant

Reason:
I wound up rewriting it almost entirely, probably easier to just submit it as a new patchset (I9acff6a2).

https://gerrit.wikimedia.org/r/188938

Change 189050 had a related patch set uploaded (by Anomie):
Allow for "authentication-only" consumers

https://gerrit.wikimedia.org/r/189050

Patch-For-Review

Anomie claimed this task.Feb 6 2015, 7:56 PM
Anomie added a project: MediaWiki-Core-Team.
Anomie moved this task from Backlog to Needs Review/Feedback on the MediaWiki-Core-Team board.
Ricordisamoa added a subscriber: Ricordisamoa.

Hm, why only permissionless apps? Other big sites which use OAuth do not make this distinction? Try GitHub, you get asked for permissions the first time, but then you just get redirected. You can also make the token expire after some time and then they have to reauthorize. But to have to authorize every time if they are any permissions is also not good security practice. Security research is showing that the danger is user habituation to the prompt. Then they will stop reading it. And next time an evil developer will change permissions requested, they will just click OK. Habituation to prompts are a big problem. So it is better to make a prompt only when there is something important. Like permissions being asked change. Or token expired. Or there was some other security issue (login happened from strange IP, geoIP is showing multiple connections from multiple continents, etc.).

I would ask you to reconsider. Or make it at least optional, so that user can opt-in or opt-out with a checkbox when confirming the dialog ("Remember my confirmation for 30 days"). But I really think you should not be prompting unnecessary and not even provide such an option.

I'll note that Github, Facebook, etc have all had account compromise attacks with their OAuth implementations. So changes like this need a thorough careful review.

In this case, Consumers that are using http callbacks, and the authorization can be started via GET request, would be vulnerable to a local network attacker silently stealing a validation code from a victim who is logged in and happened to have authorized the app previously. (i.e., use social engineering / network attack to inject img tag that points to authorization endpoint, browser is redirected to mediawiki, silently authorizes and redirects to callback. Browser makes an http request to the original consumer, which local network attacker can intercept/steal the validation code). For permissionless apps, this isn't much benefit to the attacker, but if the app has permissions, that could be bad.

Let's start with permissionless apps, and might extend it to apps without admin permissions that use https in their callback.

Security is always a trade-off. Usability, security, attention, habituation, all those things. The issue is that even with asking the user for permission every time you can introduce security issues. Maybe it makes you feel better because it becomes user's responsibility, but it is also a problem of you designing such a system.

Maybe the lesson we can learn from GitHub and Facebook is not that they have been compromised, but that being compromised is inevitable. So question is how to make it at least worthwhile? By maybe making the system user friendly and helpful.

would be vulnerable to a local network attacker silently stealing a validation code from a victim who is logged in and happened to have authorized the app previously.

I hope you never run OAuth over insecure connection? You allow that? I think just force HTTPS on OAuth and your simple scheme fails apart, no?

You can also include headers requesting no MIME type sniffing so that things like img tags fail apart as well. Add CSP and no frame embedding headers on top.

But yes, I agree, we should require HTTPS. I think this is good. HTTPS certificates are free this days.

But I agree. Non-HTTPS ones should be permissionless. Maybe you should update the ticket then accordingly. Provide only permissionsless apps access over OAuth, and require HTTPS for others. This is much more different reading of the ticket than only supporting permissionsless apps no matter what.

Change 189050 merged by jenkins-bot:
Allow for "authentication-only" consumers

https://gerrit.wikimedia.org/r/189050

Anomie closed this task as Resolved.May 12 2015, 8:47 PM

Marking this resolved since the specific request here is now done. Other issues should have their own tasks.

This should go out to WMF wikis with 1.26wmf6, see https://www.mediawiki.org/wiki/MediaWiki_1.26/Roadmap for the schedule.

Ricordisamoa removed subscribers: gerritbot, Unknown Object (MLST).

Is there a way to at least get the account name the user was authenticated with?
With even a simple userinfo query, flask-mwoauth gets knocked out.

@Ricordisamoa, apps that use the auth-only option should call Special:OAuth/identify, so that they get a cryptographically signed version of the user's name (and userid, blocked status, etc). More secure (integrity is cryptographically assured), and doesn't need any rights on the wiki.

@Ricordisamoa, apps that use the auth-only option should call Special:OAuth/identify, so that they get a cryptographically signed version of the user's name (and userid, blocked status, etc). More secure (integrity is cryptographically assured), and doesn't need any rights on the wiki.

@valhallasw How to do it in flask-mwoauth?

@Ricordisamoa, apps that use the auth-only option should call Special:OAuth/identify, so that they get a cryptographically signed version of the user's name (and userid, blocked status, etc). More secure (integrity is cryptographically assured), and doesn't need any rights on the wiki.

@valhallasw How to do it in flask-mwoauth?

ping :)

This is currently not supported in flask-mwoauth.