Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open redirect vulnerability when prompt=none #61

Closed
meagar opened this issue Feb 7, 2019 · 5 comments
Closed

Open redirect vulnerability when prompt=none #61

meagar opened this issue Feb 7, 2019 · 5 comments

Comments

@meagar
Copy link
Contributor

meagar commented Feb 7, 2019

tl;dr Doorkeeper OIDC can be provoked to blindly redirect the browser to whatever site is sent in redirect_uri paramter when prompt=none.


Given an otherwise valid authorization attempt with prompt=none, if an error can be provoked, the user is redirected to whatever redirect URI is passed in through the redirect_uri parameter with an error message in the query string.

For example, assume I have a Doorkeeper-backed Identity provider at identity-provider.com. It has an application with a client ID of 123 and a redirect-URI of https://real-site.com/callback.

If I have previously authorized with identity-provider.com with the openid profile claims, and I issue a new authorization request with only the openid scope, and prompt=none, an error is raised because the claims I'm requesting don't match the claims I previously authorized, but prompt=none prevents me from reauthorizing.

The error causes me to be redirected to whatever redirect_uri is included in the request, even if it's not a valid whitelisted redirect URI for the subject application.

A sample request, assuming I'm already authorized (newlines added for clarity):

https://identity-provider.com/oauth/authorize?
  client_id=123
  redirect_uri=https%3A%2F%2Fattacksite.com&
  response_type=code&
  scope=openid&
  prompt=none

This request sends me to (again, newlines added for clarity):

https://attacksite.com/?
  error=consent_required&
  error_description=The+authorization+server+requires+end-user+consent

At this point, attacksite.com can display a phishing form; given that I clicked on a link that started with identity-provider.com to start the authorization flow, it's possible that I can be tricked into entering my credentials into the attacking site. This is (I believe) an example of a Dangerous URL Redirect.

The problem seems to be in how exceptions are rescued:

https://github.com/meagar/doorkeeper-openid_connect/blob/12685b19af46e0e1abcf6c74efe919268fec34f8/lib/doorkeeper/openid_connect/helpers/controller.rb#L22

error = ::Doorkeeper::OAuth::ErrorResponse.new(
  name: exception.error_name,
  state: params[:state],
  redirect_uri: params[:redirect_uri])

This line extracts redirect_uri directly from the incoming parameters, and does nothing to validate it before redirecting the browser there on subsequent lines.

I think the correct behaviour here is to render a 422 error, rather than redirect the browser, regardless of the prompt=none.

@toupeira
Copy link
Member

toupeira commented Feb 8, 2019

@meagar thanks again :)

I've prepared a PR in #66 to catch this, I would appreciate it if you could take a look!

Also, not sure if this is serious enough to warrant a CVE? Let me know if you have experience with that, otherwise I'll look into it.

I think the correct behaviour here is to render a 422 error, rather than redirect the browser, regardless of the prompt=none.

I'm not sure if the 422 error should have precedence, since we're already returning the OIDC/OAuth error. The code in #66 currently returns a 401.

@toupeira
Copy link
Member

Released with version 1.5.4

@meagar
Copy link
Contributor Author

meagar commented Mar 15, 2019

Sorry, I've been away from the Internet for personal reasons.

I don't know if this warrants a CVE, but it'd be fun for me to create one. Would you be OK with that? I think it's wise to publicly disclose this problem, since it's a very real attack vector.

@toupeira
Copy link
Member

@meagar thanks, but I was curious as well and requested one through iwantacve.org :) I got an automated reply a few weeks ago and just inquired again about the current state.

I also see now they have an official form online at https://cveform.mitre.org/, it used to redirect to a Google form so maybe that's why my request got lost.

@toupeira
Copy link
Member

@meagar ok had to submit a new request and got a CVE assigned now, see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-9837

I credited you as the discoverer but looks like it's not displayed anywhere, sorry ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants