Hacker News new | ask | show | jobs
by kisamoto 806 days ago
Okay we can go through a threat model. We have a user, a service and an attacker.

Scenario 1: Attacker external to service

With TLS and server side encryption (generally at rest), if an attacker breaches the service they will have full access to all user data. The server has the encryption/decryption keys.

With client side encryption, if an attacker breaches the service they have access to many encrypted blobs that they need to decrypt. If the attacker wants to do this they have to create and plublish a malicious JS and update any resource integrity before waiting for the users to use the malicious version and even then will only get a subset of user keys.

Scenario 2: Attacker internal to service

With TLS and server side encryption, a malicious employee can generally get access to the unencrypted data. Once again, the server will have a copy of the key. Whether by accident or on purpose, plain text user data can be leaked into logs, dumped into backups etc.

With client side encryption, the attacker only has access to ciphertext. Again, they would need to publish a malicious library, bypass any resource integrity at the same time and wait - remaining undetected - for every user to log in so their keys could be siphoned away.

-----

It may be the case that the server needs access to plain text data in which case a more complex approach using a unique user key pair where the public key encrypts the data after processing so the server cannot decrypt it could be utilized. But even then, there will still need to be some JS sent to browser for that logic.

If there is no business reason for the server to see the plaintext data, client side encryption should be preferred.

1 comments

No. In scenario 1, with TLS, an attacker gets access only to data corresponding to incoming requests. The same thing clientside Javascript cryptography code does to push secrets out to the client (either by deriving keys from memorable secrets or using local storage) works to store secrets serverside encryption can use; lots of encrypted cookie systems have been built to do this.

Your scenario 2 analysis works by suggesting that attackers can't easily subvert the Javascript contexts of clients (it mentions for instance "resource integrity"). But every request for any resource that alters the DOM or loads code allows an attacker to pull this off; it's the premise of the attack. This is an even weaker case for browser JS crypto.

I think the big premise mismatch we have is that you're assuming I'm saying "just use TLS and store keys on the serverside".

I feel like discussions about WebCrypto always fall apart in arguments over abstractions, like software update versus HTTP requests. But I'm saying, it seems like you can literally just skip all the clientside cryptography, stuff keys in cookies (or whatever), and do all the encryption serverside, and end up with the same threat model, which to me is telling.

I don't think people are crazy for pushing back on this. People smarter than me disagree about it. I wonder if David Adrian wants to take a swipe at this argument.

Ah - you might be right that there are some crossed wires here as I was imagining a "just use TLS and store keys on the server" scenario.

Could you correct me please so we're on the same discussion ground? Where does encryption happen and what mechanisms are used to ensure the security of keys?

I don't know. Just do what this library does: encrypt rows with AES-GCM. Use random keys, push the keys to clients in cookies or to store in local storage. The server "sees" the key when incoming requests arrive, but doesn't store them.
Thanks.

Hm I still would prefer plain text not leaving the device. There have been historical examples of plain text passwords ending up in logs (Twitter) so I would prefer encrypted on my device so there's no chance of interception (mistaken or purposeful) on the server.

Plus this would result in a loss of features - keys would then live only on a device for as long as the cookies/storage existed. New browser/device/clean storage the keys are lost and the ciphertext unable to be decrypted.