DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Ankit Babbar
Ankit Babbar

Posted on • Updated on

Designing Secure Stateless Authentication

We will discuss the high level design for a secure authentication, with important concerns for both backend and frontend. Client Side Application could be written in React or Angular or Vue or any other modern JS Libraries/Frameworks. Backend could be in NodeJS or Go or Php or any language/frameworks your prefer.

Selection of Appropriate Technology

  • Local Storage and Session Storage are vulnerable to XSS attacks and can be easily read by Injected Scripts, they are also only available in Browser Environment.
  • In-Memory (i.e. storing it as a global variable like React Context in React App), but it is useful only if the application wants to persist Authentication in a single tab (which will be useful for Banking/Financial Websites).
  • Cookie Based Authentication Systems are equally vulnerable to XSS Attack or CSRF. But since Cookies are Universal therefore can be chosen for a persistent login which can be made secure.

Security Concerns

  • HttpOnly Cookie Attribute: HTTP only Cookie prevents the XSS or CSRF Attack. A Http Only Cookie cannot be read by Javascript but it is passed along with your request to your server.
  • Same-Site Cookie Attribute: For additional Security of Cookie you can specify the Same Site as β€˜strict’ which will make sure that Cookie is only passed when the User Hit Your Website from Browser Address Bar. Cookie is no longer available in IFrame.
  • Secure Cookie Attribute: Cookies in Production Environment must be sent through Https Only. Content-Type Header: By allowing application/json in the content type, prevents CSRF attack.
  • Rate Limiting DDoS Attack: Backend application must restrict number of login attempts from an IP to prevent the DDoS attack.

Authentication Tokens

A Stateless Authentication generally have two tokens, i.e. Access Token and Refresh Token.

  • Access Token: Access Token must be short lived and it must be validated in the backend application before proceeding on any operation or data access.
  • Refresh Token: Refresh Token might be issued to support automatic re-issuing of access tokens.
    • Validation: While issuing a refresh token, a record in Database can be created with an expiry, and before issuing a fresh access token, refresh token must be validated.
    • Single Time Use: After a single use, refresh token must be deleted and a fresh refresh token should be issued to user for further usage.
    • Attack Prevention: An additional mechanism to delete all users tokens or user specific Refresh Token must be available in case of security theft to block the user(s).

How to know if Access Token is expired in Frontend?

While designing the authentication system, either a third cookie (HttpOnly: false) or send response which can be stored in LocalStorage. It can then be read by client side application to decide whether a token must be refreshed before sending the next request. Cookie has the advantage that it is universal and can also be read in SSR Applications. LocalStorage will be restricted to Browser only Environment.

Logout From Application

(Frontend Concern) For implementing a better Logout on the Client Side, it is advisable that a local storage event is fired on Logout and all Tabs Automatically Update their Global Variable and expire Sensitive Information available to a particular user.

References:

https://web.dev/samesite-cookies-explained
https://stackoverflow.com/questions/19867599/what-is-the-difference-between-localstorage-sessionstorage-session-and-cookies
https://security.stackexchange.com/questions/166724/should-i-use-csrf-protection-on-rest-api-endpoints
https://security.stackexchange.com/questions/170477/csrf-with-json-post-when-content-type-must-be-application-json

(HTML forms generated from Backend Application are not part of scope of this article and therefore we don't expand on CSRF Token which is an important security concern for HTML Forms).

Top comments (0)

Super Useful CSS Resources

>> Check out this classic DEV post <<