ory / hydra

The most scalable and customizable OpenID Certified™ OpenID Connect and OAuth Provider on the market. Become an OpenID Connect and OAuth2 Provider over night. Broad support for related RFCs. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=hydra
Apache License 2.0
15.66k stars 1.5k forks source link

Login request admin endpoints are unaware of login request having expired #2820

Closed Conduitry closed 1 year ago

Conduitry commented 3 years ago

Describe the bug

Hydra Admin endpoints do not appear to be aware of when a login request has already expired. Depending on OpenID client configuration, this will result in an error message being displayed to the end user that the identity provider using Hydra has no way of knowing about or guarding against.

Reproducing the bug

Steps to reproduce the behavior:

  1. Initiate a login using Hydra.
  2. Wait until the login request TTL has passed.
  3. Attempt to continue the login.
  4. Observe that the internal requests to /oauth2/auth/requests/login and /oauth2/auth/requests/login/accept succeed.
  5. Observe that the browser's request to /oauth2/auth fails.

Server logs

The first four entries here are the successful get login request and the accept login request. After that are the browser's (redirected) request to the public OAuth endpoint and its subsequent redirection to the OpenID client's callback endpoint with the error.

level=info msg=started handling request http_request=map[headers:map[accept:*/* accept-encoding:gzip,deflate,br connection:close user-agent:node-fetch] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.5:52298 scheme:http]
level=info msg=completed handling request http_request=map[headers:map[accept:*/* accept-encoding:gzip,deflate,br connection:close user-agent:node-fetch] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.5:52298 scheme:http] http_response=map[headers:map[content-type:application/json; charset=utf-8] size:1118 status:200 text_status:OK took:3.6841ms]
level=info msg=started handling request http_request=map[headers:map[accept:*/* accept-encoding:gzip,deflate,br connection:close content-length:189 content-type:text/plain;charset=UTF-8 user-agent:node-fetch] host:hydra:4445 method:PUT path:/oauth2/auth/requests/login/accept query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.5:52308 scheme:http]
level=info msg=completed handling request http_request=map[headers:map[accept:*/* accept-encoding:gzip,deflate,br connection:close content-length:189 content-type:text/plain;charset=UTF-8 user-agent:node-fetch] host:hydra:4445 method:PUT path:/oauth2/auth/requests/login/accept query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.5:52308 scheme:http] http_response=map[headers:map[content-type:application/json; charset=utf-8] size:343 status:200 text_status:OK took:9.8726ms]
level=info msg=started handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 connection:close cookie:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". dnt:1 referer:http://127.0.0.1:10040/login?login_challenge=79c2dcee500e4e8b851b2256478cc3f8 sec-fetch-dest:document sec-fetch-mode:navigate sec-fetch-site:same-origin sec-fetch-user:?1 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0] host:hydra:4444 method:GET path:/oauth2/auth query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.6:52248 scheme:http]
level=info msg=access denied audience=audit error=map[debug: message:request_unauthorized reason:The login request has expired. Please try again. status:Unauthorized status_code:401] http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 connection:close cookie:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". dnt:1 referer:http://127.0.0.1:10040/login?login_challenge=79c2dcee500e4e8b851b2256478cc3f8 sec-fetch-dest:document sec-fetch-mode:navigate sec-fetch-site:same-origin sec-fetch-user:?1 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0] host:hydra:4444 method:GET path:/oauth2/auth query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.6:52248 scheme:http] service_name=ORY Hydra service_version=
level=info msg=completed handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 connection:close cookie:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". dnt:1 referer:http://127.0.0.1:10040/login?login_challenge=79c2dcee500e4e8b851b2256478cc3f8 sec-fetch-dest:document sec-fetch-mode:navigate sec-fetch-site:same-origin sec-fetch-user:?1 upgrade-insecure-requests:1 user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0] host:hydra:4444 method:GET path:/oauth2/auth query:Value is sensitive and has been redacted. To see the value set config key "log.leak_sensitive_values = true" or environment variable "LOG_LEAK_SENSITIVE_VALUES=true". remote:172.20.0.6:52248 scheme:http] http_response=map[headers:map[cache-control:no-store location:http://127.0.0.1:10040/callback?error=request_unauthorized&error_description=The+request+could+not+be+authorized.+The+login+request+has+expired.+Please+try+again.&state=teSd3u7gFKhaJRFzlOCC-QiosrrgVKXJ pragma:no-cache] size:0 status:302 text_status:Found took:5.7108ms]

Server configuration

TTL_LOGIN_CONSENT_REQUEST=1m

The TTL_LOGIN_CONSENT_REQUEST of 1m is just there to make reproducing this more convenient.

hydra serve all --dangerous-force-http

Expected behavior

When Hydra Admin is queried to get a login request, the response should indicate in some way that this login request is expired. This could be with an error response from GET /oauth2/auth/requests/login and PUT /oauth2/auth/requests/login/accept or it could be with another field in the GET /oauth2/auth/requests/login response.

I do see that GET /oauth2/auth/requests/login tells when when the login request was created, but it shouldn't be my identity provider's responsibility to know what TTL Hydra happens to be configured with at the moment (nor does there seem to be a way to directly query Hydra for this information).

Environment

Additional context

If end users can generate new login requests on demand, what sort of attack is having a limited TTL on the login request attempting to mitigate?

Conduitry commented 3 years ago

I'm able to reproduce this with the quickstart app here by editing quickstart.yml to include a short value for the TTL_LOGIN_CONSENT_REQUEST environment variable.

The logs indicate that the GET to retrieve the login request and the PUT to accept the login request both succeed, and then browser is redirected to http://127.0.0.1:4444/oauth2/auth?xxx which then redirects to http://127.0.0.1:5555/callback?error=request_unauthorized&error_description=The+request+could+not+be+authorized.+The+login+request+has+expired.+Please+try+again.&state=xxx

gunsluo commented 2 years ago

any plan on this case? I would like to get the status of whether the login request is expired through Hydra Admin endpoints, So that we can handle expired login requests at the login provider side, instead of redirect expired error messages to client side. if the system has many clients, It's a repetitive job.

So do we have any other way to get expired information of login request from Hydra Admin endpoints? @aeneasr

aeneasr commented 2 years ago

For context please see: https://github.com/ory/hydra/pull/2823#issuecomment-953953549

We could probably include the expired property in the response, helping you identify when such a request has expired

github-actions[bot] commented 1 year ago

Hello contributors!

I am marking this issue as stale as it has not received any engagement from the community or maintainers for a year. That does not imply that the issue has no merit! If you feel strongly about this issue

Throughout its lifetime, Ory has received over 10.000 issues and PRs. To sustain that growth, we need to prioritize and focus on issues that are important to the community. A good indication of importance, and thus priority, is activity on a topic.

Unfortunately, burnout has become a topic of concern amongst open-source projects.

It can lead to severe personal and health issues as well as opening catastrophic attack vectors.

The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone.

If this issue was marked as stale erroneously you can exempt it by adding the backlog label, assigning someone, or setting a milestone for it.

Thank you for your understanding and to anyone who participated in the conversation! And as written above, please do participate in the conversation if this topic is important to you!

Thank you 🙏✌️