1

I have a notes app that's offline-first and syncs with remote database when online.

Currently, when a user creates a note, I'm encrypting it with AES. I ask the user to enter their decryption password on every page refresh and when they enter the password, I decrypt their data from localStorage and present it. I enforce a password requirement so the passwords are going to be good if not the best.

Many people online say that this is not secure but I cannot think of any alternatives. My webapp is offline first, so it has to work with a local database somehow. I do not care if users modify the data on their end by decrypting localStorage with their decryption password because the users are responsible for creating the data in the first place and because I do not allow editing when offline, only viewing the data.

So, I'd like to ask, is it okay to store user's sensitive data in localStorage with AES encryption that they have to enter their password for before viewing their data?

0

2 Answers 2

1

I do not care if users modify the data on their end by decrypting localStorage with their decryption password because the users are responsible for creating the data in the first place and because I do not allow editing when offline, only viewing the data.

In that case, why are you even encrypting it? Bearing in mind that encryption doesn't usually prevent modification... what enemy is the encryption trying to defeat? I mean, good on you for acknowledging that you can't prevent the user from decrypting or tampering with their own data, that's important, but it's not clear what the encryption is supposed to achieve, then. An attacker who can read a browser's local storage has won; they can steal session tokens and impersonate the user across lots of sites, among other attacks, and that's without even considering how many privileges they must have obtained (probably either use impersonation or unrestricted read across the whole FS) before it's even relevant to ask about whether the notes are encrypted.

As for actual security considerations: AES in what mode of operation? Do you generate a message authentication code of any sort? If so, in what order? Are you storing any other sort of sensitive data (such as session tokens) in the local storage, and if so, how is it protected? How are you deriving the key from the password? How are you handling password reset (if at all)? How are you verifying password correctness? Do you care that the server can easily capture the plaintext notes?

4
  • For authentication I'm using next-auth. It handles the session and everything and I've also protected the API routes. The encr. is only to provide an extra layer of safe-guarding, the best I can think of right now. Because without the user's password that is only kept in the memory when user enters it on every page refresh/load, nobody can decrypt their encrypted data kept in local storage. Their data is the only thing that's encrypted and kept in the local storage, nothing else related to auth. I'm encrypting their notes (which is basically a javascript array) using CryptoJS' AES method.
    – Wor Chan
    Commented Nov 17, 2022 at 10:31
  • CryptoJS' AES implementation uses CBC by default, and does not support any authenticated encryption modes. Unless you are separately and manually generating and verifying a MAC (probably an HMAC), your ciphertext is partially vulnerable to tampering by an adversary who knows anything about its content. With that said, you still haven't answer the question: who is the adversary? What is your threat model, such that this encryption mitigates some threat?
    – CBHacking
    Commented Nov 18, 2022 at 12:48
  • Encryption mitigates the XSS threat of using local storage, no? Commented Apr 17, 2023 at 17:02
  • @pcalkins Not really. Encryption mitigates offline access to the data, but XSS only works while the user is logged for the app. For the app to work at all, the decryption key needs to be available to JS. Anything that's available to JS is available to XSS (which is after all just JS). Besides that, the data by necessity is decrypted while the user uses the app - if not decrypted in storage, then at least decrypted in the DOM - and the XSS-injected script can just read (and modify) it out of there. XSS can do anything that legit script can do, to a first approximation.
    – CBHacking
    Commented Apr 18, 2023 at 5:07
1

The answer depends exclusively on the threat model that you've established for your application; it is the model that will help you decide whether your counter measures are adequate for the threats that you've identified, and it is the model that will point out any extra steps you may need to take to protect your assets (notes).

So, what is your threat model? (e.g. what assets are you trying to protect, who is your threat, in what ways can the threat actors decrease the value of your assets).

Establishing a threat model will give you the answer to your question.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .