Hacker News new | ask | show | jobs
by devinsit 1874 days ago
That's the thing, the key isn't controlled by me. The key is derived from your account password. If you want some more technical details, feel free to check out https://ufincs.com/policies/security. tl;dr Yes, that browser API is called WebCrypto.

As for storage, all data is kept in-browser in local storage (specifically, IndexedDB), until it gets saved to our database. And before it leaves the browser to be saved in our database, it gets encrypted using the user's key.

Finally, if you only ever use the 'no account' option (https://ufincs.com/noaccount), then all your data is only ever stored in-browser; it never gets saved to our database because you don't even have an account to save it to! Feel free to monitor the network requests to prove it for yourself (or even turn off your network connection).

Hopefully that makes things more clear.

1 comments

So, when you change your password, all data flows back to your browser to be decrypted, then gets re-encrypted, and sent back?
Hmm, that's a good question to add to the Security doc!

Not quite. See, we make use of a scheme called envelope encryption. That means we have two separate keys: one to encrypt your data (the 'data encryption key' or DEK) and one to encrypt the DEK (the 'key encryption key' or KEK). We use the KEK to encrypt your DEK to get something called the 'EDEK' (or 'encrypted data encryption key'). The EDEK is what we store in our database.

Something that never changes after you sign up is your DEK. This is completely random and not dependent on your password.

What is dependent on your password is your KEK. So when you change your password, all that actually changes is your KEK. With your new KEK, we just re-encrypt your DEK to get a new EDEK, and we store that new EDEK in our database. Again, the Security doc (https://ufincs.com/policies/security) outlines the basic process.

So no, all your data isn't passed back to the browser to be decrypted and re-encrypted when you change your password, but thanks for the question!

“With your new KEK, we just re-encrypt your DEK”

⇒ when users change their password, you have access to the DEK (you decrypt it and then encrypt it with the new KEK)

“one to encrypt your data (the 'data encryption key' or DEK)”

⇒ when users change their password, you could decrypt their data.

I think this boils down to “you don’t store user passwords, but when users change their password, they must trust you to not look at your data or store the KEK”.

Where’s my error?

The 'error', as you put it, is that the password change process (i.e. the changing of the KEK and the re-encryption of the DEK into the EDEK) all happens client-side (except for the part where we verify your old password against the hashed version in the database, for obvious reasons).

'We' have 'access' to your DEK at all times — if you define 'we' as the 'client-facing portion of the app'. All of the encryption/decryption, key management, etc happens on the client-side (i.e. in-browser). Remember, as part of signing in to the app, the EDEK is transmitted from our servers and decrypted client-side so that the client can then use that DEK to decrypt your data.

If we instead redefine 'we' to be the backend servers, database, or even myself personally, then 'we' never have access to your keys nor data.

The fact is, there's nothing special about the password change process itself. It's essentially the same as the sign-up process. Nothing is especially exposed during the password change process that isn't exposed during the sign-up process (again, the DEK is present on the client-side the moment you sign up or sign in, although the KEK is slightly more ephemeral than that).

However, I do understand the implication you're making here, and here's the darker side of it: 'we' (uFincs) could change the client-facing portion of the app to steal your DEK (or your password, or even your data) and send it off elsewhere. This is... just true of any piece of software. It just so happens that, since web apps can be arbitrarily updated, it's a lot easier for us to act maliciously if we so chose (although, at least with web apps, inspecting network requests is quite easy).

So indeed, there is an element of trust here. You trust that I (or the entity known as 'uFincs') won't change the code in such a way that the security of the app is compromised. You also have to trust that we have such security measures in place that make it harder for some third-party malicious actor to forcefully change the operation of the app.

uFincs is not a trust-less system. Unfortunately, due to the nature of web apps (or even most apps for that matter), it simply cannot be. Anytime the code can be updated (and can't be audited), there is effectively zero security (for those who are particularly security-conscious). So if your (the general 'your') financial data is so sensitive that any chance of a leak would be utterly catastrophic, then don't even think of using uFincs.

But I like to think that putting these measures in place (particularly, using client-side encryption, not connecting to banks, not using any in-app analytics beyond our own, etc) is at least a step better — in terms of security and privacy — than what most other services do. And I like to think that, even if it's not perfect, it was still worth doing. Otherwise, I wouldn't have 'wasted' 2+ years of my life building uFincs :)

Thanks. I never would have thought “we encrypt” to mean “your browser encrypts”.

I think a few pictures showing how passwords and data flow between the user’s browser and the backend when you do various things would make your technical description easier to understand.

Lacking that, using phrases such as “our code, running in your browser” rather than that ambiguous “we”, would have made things clearer for me, too.