Skip to content
New issue

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

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

Already on GitHub? # 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 ;-)

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

No branches or pull requests

2 participants