← Back to context

Comment by gloosx

1 year ago

The security of this is somewhat questionable. On client device the notes are stored in plain text, so even another user from the same machine can read them.

For syncing it also sends a `username+password+salt` SHA-256 hash to the server, together with the username which makes password easily pickable.

Giving we know the username AND that the salt is always 32261572990560219427182644435912532, it is really a hash crackable in minutes on a somewhat decent hardware with a simple hashcat mask attack.

Hi there. I'm happy to see people are looking at the code to verify the security. You are right about the notes being in plaintext on the client. Otherwise, you'd have to enter a password every time you open the app. The issue I was trying to solve wasn't really trusting my own system but trusting the server and the middlemen.

About the encryption, adding the username+salt prevents the use of rainbow tables by hackers but hashcat mask attack can be prevented by a strong password to make it infeasible. But yeah, if you pick an all lowercase 8 letter password, it can be cracked pretty quickly.

Also please note that, the server doesn't store the hash but hashes it again with yet another salt and stores the double hash. When logging in, the server issues a long token for the client so that the client doesn't have to store the password or its hash anywhere. Additionally, neither hashes are used for encryption and decryption and each note's encryption is salted differently.

edit: I'd love to hear suggestions on how to improve the situation even for shorter passwords.

  • Even with a strong password – my laptop today can do 1100 MH/s which makes it quite feasible. One of the potential attack vectors can look like this: a malicious actor takes this and reskins the UI, then hosts and does the marketing, his server stores the NGINX logs with /login requests for some time, preserving the password_hash and username params silently. Then after a while he spends few weeks cracking the passwords for every account and syncs their notes, then parsing them for passwords/sensitive info.

    As for suggestions, this could be enforced by making use of a system-level keychain, but I don't know if it is possible within a sandboxed environment like PWA. Some stronger derivation method would help too, like the industry standard is pbkdf2 with at least 600000 iterations for SHA256. Lastly, end-to-end encryption usually implies some kind of protection against man-in-the-middle attack, like a certificate pinning mechanism

    • Actually I'm using pbkdf2 with 100000 iterations of sha256 for the encryption, but not for hashing the pass. That will certainly add a few orders of magnitude to the infeasibility of cracking the password hash when the server itself is not to be trusted. I'll implement that and thanks for bringing it to my attention.

      But I don't think a strong password can be cracked that quickly. Let's say you use a 12 character long lowercase, uppercase, digits and some specials chars. That should give you at least 60^12 possibilities. At 1BH/s, that would take 70k years. Is my calculation wrong?

> The security of this is somewhat questionable. On client device the notes are stored in plain text, so even another user from the same machine can read them

Depending on the threat model this might not be an issue. For my particular case where the notes must be kept away from ultra-capitalist companies it's more than enough

> Giving we know the username AND that the salt is always 32261572990560219427182644435912532, it is really a hash crackable in minutes

This is way way more worrying