How to store user data client side
Tags: security, webdev, javascript, database
Published: 2023-05-28 11:41:57

Modern web applications often store and display user data in the browser to personalize the user experience. This might include non-sensitive data, such as user preferences or UI state, and sensitive data, like usernames or email addresses. Data can be stored in various ways, including in cookies, LocalStorage, SessionStorage, or IndexedDB. However, storing sensitive data in the browser will open your application to security risks, such as Cross-Site Scripting (XSS) attacks.

### Cross-Site Scripting (XSS) TL;DR

Cross-Site Scripting (XSS) is a web security vulnerability that allows attackers to inject malicious scripts into web pages, exploiting unvalidated or improperly escaped user input. These scripts can steal sensitive information or perform actions on behalf of the user, posing serious security risks.

## What you should do TL;DR

The more persistent your user information storage is the more susceptible to XSS attacks your application is. Therefore, the most secure approach is to refrain from storing any sensitive user information in the client-side. However, if user data storage is inevitable, the most secure approach is to fetch it on-demand, using it only when necessary, and avoiding persisting this information across pages. This practice significantly mitigates potential risks, ensuring a safer user experience and a more secure application.

If you absolutely have to store user information in the browser here are a few options organized by more susceptible to XSS and less susceptible to XSS.

## Less XSS vulnerable options

### Fetch user information when needed

Once the user logs in, you can make an API request to fetch the user's profile information, including their email.
You will need to re-fetch this information when the user reloads the page. But if you only request the information when needed, malicious scripts have a smaller attack vector.
If you store this information in the application's state your attack vector increases, but will be smaller than in the more persistent storage options explained below.

## More XSS vulnerable options

### Store the email in a non-HTTP-only secure cookie
You can store the email in a cookie that isn't set to HTTP-only. This would make it accessible to JavaScript through the document.cookie API. Cookies also persist across page refreshes. But, like LocalStorage, cookies are also vulnerable to XSS attacks.

### Use the Session or Local Storage
On successful login, you can store the user's email in the Session Storage or Local Storage. The email can then be retrieved and displayed whenever necessary. However, as discussed in previous responses, this approach has some security risks.

### Embed the email in the token (JWT)
You can include the email in the payload of the JSON Web Token (JWT) that is sent to the client after a successful login. The frontend can decode the token and extract the email to display it. However, be aware that the information in a JWT is not encrypted, only encoded.

### Embed in the page HTML
When the server generates the HTML for the page, it can embed the user's email directly into the script. This can be a good option if your server renders your pages, but it won't work if your frontend is a single-page application that doesn't regularly receive full page updates from the server.

**In conclusion**, no matter how you go about it storing user data on the client side will open up your application to security risks, such as XSS attacks. The principle of reducing attack vectors guides us towards best practices: it's safest not to store any sensitive user information client-side if possible. If storage of user data is essential, minimizing persistence and fetching data on-demand is the recommended approach.

**Remember to ensure you're complying with all relevant privacy laws and regulations when handling user data.**