Intro to Security - raisercostin/software-wiki GitHub Wiki

Concepts

  • authentication vs authorization - https://auth0.com/intro-to-iam/authentication-vs-authorization/
    • Authentication is the process of confirming the identity of a user or a device (i.e., an entity) by showing "credentials"/"factors":
      • presenting a hard to fake object: ID, passport, papers, sigil, ring, badge
      • you own a device (like a mobile phone so you can receive an SMS with a code)
      • showing the system that you know something
        • username and password
        • some tokes printed (like in two factor auth where you generate a list)
        • responding questions about your account (bank) your history(windows asking your pet name)
    • Authorization refers to the process of verifying what resources entities (users or devices) can access, or what actions they can perform, i.e., their access rights.
      • usually authorization is handled by tickets/security tokens.
      • security tokens
        • (from) - In the diagram above, SPA = Single-Page Application; AS = Authorization Server; RS = Resource Server; AT = Access Token; RT = Refresh Token.
        • oauth2 uses access and refresh tokens that are opaque
        • oidc (open id connect) uses ID tokens that contain identity data
        • Access tokens are issued to third-party clients by an authorization server with the approval of the resource owner. The client uses the access token to access the protected resources hosted by the resource server.
          • some are JSON Web Token (JWT)
        • Refresh Tokens are credentials used to obtain access tokens. Refresh tokens are issued to the client by the authorization server and are used to obtain a new access token when the current access token becomes invalid or expires, or to obtain additional access tokens with identical or narrower scope.
        • Access Tokens vs Refresh Tokens
        • Maybe we should switch the talk to Revokable Tokens vs NonRevokable Tokens
          • Since the refresh and access tokens are terms loaded with a lot of semantics a terminology shift could help?
            • Revokable Tokens - tokens that must be checked with authorization server
              • could be chained (see RTR - refresh token rotation)
              • can be used to create NonRevokable Tokens, but can also be used directly (when volumes are small and the check doesn't become a burden)
              • can be long lived but that depends on how often the user must be bothered with credentials (username/password) to get a new one
              • can be invalidated on RTR or any other suspect behavior
            • NonRevokable Tokens - tokens that are self contained and do not need to be checked with authorization server
              • are useful for big data, distributed servers/api calls to scale horizontally
              • should be short lived (since are non revokable)

            • In 2020 it become accepted that refresh token can also exist in the browser (initially was offered for backend systems) - see https://pragmaticwebsecurity.com/articles/oauthoidc/refresh-token-protection-implications. Because of this the focus was switched from the "refreshability" (how would a backend in absence of a user prolong the access to an api) to "revokability".
            • So, to me it looks safer to read the refresh tokens as Revokable Tokens and access tokens as Non-Revokable Tokens (maybe Fast Expiring Non Revokable Tokens) .
            • As a side note about good practice in 2021 a system can always start with revokable tokens and move to non-revokable when the pressure on authorization server increases.
        • References about tokens
    • types of tokens
  • PKI - Public Key Infrastructure

Implementation spec

Analysis2

There are a lot of discussions related to what to do with access and refresh token. The latest and clearest explanations I found are at

It looks like there is convergence on the fact that:

  • both reach the client app (browser)
  • refresh token should be sent only when a new access token is needed and only to the authorization server (so a specific path if is the same server)
  • they could be stored in memory, cookies or storage (but will be accessible from javascript)
    • in memory is the most secure but they are lost when tab/browser is closed
    • as cookies - if used as cookies the client code doesn't need to know anything
      • httpOnly cookies to limit their use
      • refresh token should be only for authorization server and specific path
    • you must be careful to the javascript that you have
  • if used as local storage the client must intercept calls and add them to header as Bearer tokens.
  • Initially RefreshTokens where released to backend servers to be able to access resources on behalf of the user. But the backends were more secure. When used in browser they must be used with RTR.
  • Also refresh tokens submits to revoking (also more expensive) meaning they must be checked by authorization server
    • a change of client-id and client-secret will invalidate them automatically
    • a clear of the valid refresh tokens will also invalidate the further use

Additional hints:

  • Refresh Token Rotation (RTR) you could minimise the steal and use of refresh tokens by chaining them one after another. whenever someone wants to fork your chain you will discover by having an invalidated refresh token that will force a complete reauthentication
    • a refresh token should be used only once when a new refresh token is generated
    • when a bad refresh token is used all refresh tokens could be invalidated and the user forced to reauthenticate on all devices "There is a scalability reason, in that the access_token could be verifiable on the resource server without DB lookup or a call out to a central server, then the refresh token serves as the means for revoking in the "an access token good for an hour, with a refresh token good for a year or good-till-revoked."

There is a security reason, the refresh_token is only ever exchanged with authorization server whereas the access_token is exchanged with resource servers. This mitigates the risk of a long-lived access_token leaking (query param in a log file on an insecure resource server, beta or poorly coded resource server app, JS SDK client on a non https site that puts the access_token in a cookie, etc) in the "an access token good for an hour, with a refresh token good for a year or good-till-revoked" vs "an access token good-till-revoked without a refresh token." - https://mailarchive.ietf.org/arch/msg/oauth/vSmJ0zjQzZFjeFbRz_qpvjfpAeU/

Analysis1

In connection with #4295 . Now that the authorization token verification is done, after 1min, the token will expire.

  • The server should report that the access token expired (now it just fails with 500 - Failed to create XUserInfo from token caused by Token is not active )
  • The client should use it's refresh token to get a new access token
    • current implementation (@maku2 ) returns only the access token while ignores refresh token.
      • From here https://auth0.com/docs/secure/tokens/refresh-tokens/get-refresh-tokens I deduce that both can be returned to the client app:
        • Access token will be used to call the resource server (in our case the backend server but all urls) - and it will be checked fast without further presure on the authorization server (keycloak)
        • Refresh token will be used to call the authorization server (in our case the backend server getAccess tokens) - and it will be slower since will translate into a call to the authorization serve (keycloak) and could also lead to a reauthentication
      • Anyway both are needed in the client, otherwise we will need a "session" mechanism in the intermediate layer that will create a 3rd token: session token and will keep in memory the connection between refresh token and session token.
  • strategies to get new access token from best to worst
    • These strategies are analyzed extensively in oauth and are named authorization flows.
    • See more references on refresh vs access tokens
    • Considered Strategies/Options/Flows from best to worst:
    1. client decodes jwt token and find outs the expiration moment
    2. server returns 401 - upon the expiration message returned by server with 401 - https://stackoverflow.com/questions/8855297/token-expired-json-rest-api-error-code
      • #4356 if access token expires (or any 401) reason the userinfo is not called anymore, a refresh token should be called
    3. client has an expiration policy - automatically via a configurable timeout in client
      • is already implemented like that but we should let the authorization server to decide the expiration policy that will be used to set the expiration inside jwt token
    4. client uses refresh token - the server could return a new access token directly => only if it receives a refresh token => but this is a bad practice

References

Tools