2

Let's see the following scenario:

  • "GutHib" is a fictional hosting service in the form of an online webapp for the fictional DVCS software "Gut".
  • Alice logged in to GutHib with her password and 2FA, providing a strong proof that she really is the one who the registered account belongs to. (Let's assume she did well keeping her password and 2FA information safe, and no one else can access her account.)
  • Alice set remember me to true at login, so she does not need to log in every time she wants to browse on GutHib.
  • After 3 months of the first & only login to GutHib, Alice accidentally left her laptop open in a café while paying with her phone at the cash register. An attacker came to the laptop, opened GutHib, and since Alice set the remember me to true, the attacker could access the site's functionality while impersonating Alice, and clicked on "Transfer repository ownership" button at an important repository's admin page. This only required to be logged in, so one of Alice's important repos were stolen.

With applying re-authentication for this sensitive & destructive writer operation, GutHib could have prevented stealing Alice's code: the password is only known by her, also the phone with the 2FA app was also at her.

E.g. the api/transfer-repository endpoint could require an elevated session type based on password/2FA re-entry (e.g. PasswordSession or PasswordSession + TwoFactorSession, valid for 10min), or even a OneTimeSession acquired with the TwoFactorSession, which is specifically requested and signed for one particular endpoint call (valid only for the next endpoint call it is requested for).

How come that today's industry standards or best practices do not support these re-authentication flows?


tl;dr

  1. Is there a standardized way to ensure that the user making a request to a server endpoint (which performs a sensitive, destructive writer action) really sits in front of the computer and is the same user who logged in 3 months ago with remember me, and not a malicious attacker?
  2. This a real attack model. How come this is not supported by today's authentication & authorization industry standards like OpenID Connect & OAuth 2.0? Am I missing something?
  • I'm a little confused. It is standard to ask for re-authentication when performing sensitive actions. – schroeder Jun 8 '19 at 20:48
  • I was confused too. That's why I asked how the standards align to this meta-standard of re-authenticating users when performing sensitive actions. As the below answer states correctly, the acr claim specifically solves this problem. – Soma Lucz Jun 8 '19 at 20:58
1

The "level of assurance" of the authentication (how much you trust that the user is who she says she is, is usually stored in the standard-defined claim "acr". It's usually between 1 and 3, and is set during login based on the form of authentication. 2 factors give a higher acr than just a password, for instance. NIST SP 800-63 gives some more details.

What you can do, is to require a certain acr value for important endpoints, and require reauthentication if the level is not high enough.

This solves your problem, if you have a mechanism to reduce the acr value over time or when issuing long lived sessions. Then Alice is only able to use the "ownership" functionality for a short period after logging in.

|improve this answer|||||
  • Thank you for your answer. Now that I know what to look for, I found it in the ID Token section of the OpenID Connect specification. I should be reading specs more carefully. – Soma Lucz Jun 8 '19 at 21:00
1

Geir's answer is great and valid for OpenID Connect. One note though: as of today we're still struggling with SSO solutions (Single-Sign On, supporting OAuth2 / Openid Connect / SAML2, etc. protocols) that support such decaying LOAs. Be warned. In addition the concept of authenticated session is not standardized in any OAuth2 or OpenID Connect specification.

Your question was about requiring higher assurance for APIs. The access control protocol for APIs is OAuth2, which does not have an ID Token, and doesn't have LOAs. Here you have 2 solutions:

  • Use a specific scope for more sensitive API endpoints, or actions (e.g. PUT), and reduce the lifetime of refresh tokens when it has such a "sensitive" scope. When the refresh token expires, the client redirects to the authorization server where the needed authentication and authorization policy is applied (for instance, the transfer-repository OAuth2 scope requires a second factor used less than 1 hour minutes ago). Solutions' support is very poor
  • Embed the current LOA information in the access token data (be it on the /introspect endpoint or embedded in a signed JWT) and have the API check against it. Solution support is wider, but this is not standardized because, as said before, the concept of authentication session is not standardized

There's also a difference of philosophy between these two approaches: where should the authorization policy be enforce? In a centralized way on the authorization server (scope-based solution) or in a decentralized fashion on APIs (LOA bound to the access token solution)?

Also, none of these solutions support the transaction use-case.

|improve this answer|||||
  • Thank you for your comment. It's interesting to think about this philosophical difference. For the first look, we will need both. We will need the Introspection Extension — I mean even if we set the token validity to the shortest sensible value (e.g. 1 minute, which already totally contradicts the non-resource intensive verification/refreshment & statelessness of OAuth 2.0 tokens), if Alice logs out, the attacker will still have a 1 minute time window to steal Alice's code. – Soma Lucz Jun 9 '19 at 9:10
  • This means that in all cases we will need a layer of additional logic in our own APIs to verify the token against the /introspect endpoint. Since the LOA bears the same kind of semantic information (e.g. Level 0 LOA could be that the user is not even logged in), it is bound to the current authorization request. Thus requiring the API endpoints to enforce its own authorization policies by checking the token and the LOA is not pointless in my opinion. – Soma Lucz Jun 9 '19 at 9:12
  • And scopes could still be used for truly stateless actual authorization policies the user has/lets access to the given app. These are stateless in the meaning of 1.) Alice's rights to a feature will not change during automated flows, or 2.) an app's delegated access rights will not change during the lifetime of its access. What do you think? – Soma Lucz Jun 9 '19 at 9:16
  • 1
    Actually access tokens (AT) can be either stateful or stateless. Stateful means use of RFC7662 and a opaque format. Stateless means using JWTs, which is not a good idea in my opinion. When using stateful access token, it's common to cache it for a few seconds or minutes at the API level (if your API is distinct from the authorization server (AS)). Whn using JWTs, there's no need for /introspect check but you need to verify the signature every request, plus these AT are not revokable. – Tangui Jun 9 '19 at 11:00
  • 1
    Regarding the difference between OAuth2 and OpenID Connect (OIDC), you can think of OIDC as a website to website authentication protocol, while OAuth2 is an API access control protocol. – Tangui Jun 9 '19 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.