← Back

Tackel OAuth Sensitive Information

Published

12 October 2023

Tags

Security
Web Development

Background

This was my experience when handling an authentication in my office’s project. The project is so strict with security compliance, thus, as a developer, we take a lot of attention to maintain the app secure enough.

Mostly in my company’s projects are using Identity Provider (IdP) to provide authentication and authorization process in the application. In short, the IdP server will generate the user identity information that consists of an access token and send it to the UI side to be stored. Mainly if you are using the UI third-party library to manage the information like oidc-client, in default they will store it in the local storage unless the developer determines the other location (cookies or session storage). Well, this practice is used in most of our projects.

Until we got an issue regarding the sensitive disclosure information from the Aegis team after they did Vulnerability Assessment and Penetration Testing (VAPT). In detail, our practice to store user identity information in local storage is considered vulnerable because the information stored in local storage is still persisted even after a user closes the browser, and it also accessible with JavaScript which may lead to session stealing.

The security engineer team's recommendation was to change the storage to the safer one that can't be accessed from the client side, which is using cookie storage with secure and httponly flags.

Why use cookie? The main reason the Aegis team recommended using cookies storage instead of local storage is that cookie storage provides more secure options or attributes to restrict access to stored sensitive information.

Source: Using HTTP cookies - HTTP | MDN (mozilla.org)
  • httponly has to be set to prevent XSS as it blocks any Javascript accessing the cookies.
  • secure has to be set to prevent MITM attacks as it only allows cookies to be sent to the server over HTTPS protocol requests.

After some implementation to try to change the storage to cookies, we faced some blockers.

Frontend side

The blocker that we faced on the client side is we cannot set the httponly flag in the cookie. Sadly, this flag can only be set from the server side.

Backend side

When we tried to ask the team that handling IdP to assess the possibility to implement our request, they also found a blocker to intercept and get the token that was sent by the IdP server.

Justification

After discussing with other superiors regarding the user information storage, we provide some justifications to our current implementation.

  1. Local storage is something not shared on the network, and only accessible on local machines. – Does local storage work across different users
  2. Local storage is domain based and can't be read or write on different domain. – Cross-Domain LocalStorage – Jakub T. Jankiewicz
  3. For protecting the XSS, we have ensured that every form or input has been sanitized (since local storage is not a shared domain, we ensure that our website is protected by XSS). – Cross Site Scripting Prevention - OWASP Cheat Sheet Series
  4. We set the token to be expired in 10 minutes, so the attacker cannot use the token anymore after expired.
  5. Moving to cookies makes it more secure from simple XSS and adds more complexity to the code. The implementation of stored-in cookies is still vulnerable to advanced XSS, it's just that attackers can't steal your JWT token for later use. – security - Where to store JWT in browser? How to protect against CSRF? - Stack Overflow
    1. To store the JWT in a cookie by server
    2. Refresh the token JWT by the server (which is usually should be done by UI based on User activity)

Solutions

Frontend Checklist

There is not much to do from the UI side as you are only able to follow the authorization flow, beside you have to recheck your code again. The available JavaScript frameworks, such as Angular, React, and Vue, already provide security to ensure all variables are going through validation, but they are not perfect and still have issues. There are two required things that may help to address that issue:

  • Output encoding
  • HTML sanitizing

You can read more details about output encoding and HTML sanitizing in this article Cross Site Scripting Prevention - OWASP Cheat Sheet Series.

Backend For Frontend (BFF) Pattern

The main idea to implement the BFF Pattern is to prevent sensitive information, such as access tokens, from being stored in the browser storage, which has more security issues.

By practice, there will be an additional instance acting as a middleware between client-side, IDP and API servers. In this way, the application can isolate the sensitive information in the middleware and send it to the browser in the form of secure cookies.

More details, Web App Security, Understanding the Meaning of the BFF Pattern.

Related Articles

  1. Developer Mozilla - HTTP Cookie
  2. Stack Overflow - Answer to "Set a cookie to HttpOnly via Javascript"
  3. OWASP Cheat Sheet Series - Cross Site Scripting Prevention -
  4. OWASP Cheat Sheet Series XSS Filter Evasion