Kinto / formbuilder

Create your own forms and surveys, get your data back.
622 stars 149 forks source link

Encrypt data on client side #89

Open almet opened 8 years ago

almet commented 8 years ago

For this, we would need to generate an encryptionSecret on the client side, and pass it to the users using a hash in the URL.

Then, all records could be encrypted with it, before being stored.

The problem with this approach is the fact that validation cannot happen server side, but I believe that could be an interesting mode, depending on what you want to achieve.

I would be interested in having thoughts about this approach. cc @Natim @leplatrem and eventually a security feedback from @jvehent

jvehent commented 8 years ago

I don't have context here but based on the demo page, this looks like a form submission tool where user A posts data that user B needs to read. The only way to achieve this without the kinto server having cleartext access to the data is to publish user B's public key with the webform, encrypt data with it, and provide an interface for user B to decrypt the data later. One obvious downside is user A won't be able to read the data again after encrypting it with user B's public key.

almet commented 8 years ago

Another way would be to do symmetric encryption using a key known by user A and user B, and would let the possibility for both of them to decrypt the data afterwards, nope?

n1k0 commented 8 years ago

Out of genuine curiosity, how would you share the key between users A and B? At some point it seems they both need to access it, and I'm wondering how we could do that in a secure fashion

almet commented 8 years ago

You can pass it in the url hash, which isn't sent to the server

jvehent commented 8 years ago

I don't think that works. User B creates key xxxxxxxxx and sends user A a URL such as https://my.kinto.server/form?key=xxxxxxxxx User A enters the URL in her browser, which immediately sends it to the server with all parameters. key=xxxxxxxxx will appear in the server's access logs.

almet commented 8 years ago

No, I'm referring to the hash part, eg https://server/url/#secret

Here I believe 'secret' is not sent to the server

jvehent commented 8 years ago

The fragment should not be sent to the server indeed. It's probably going to work, but it's a rather weird flow because the form owner now needs to keep a bunch of keys in local storage somehow.

Asymmetric crypto was made to solve this very issue and doesn't require sharing key material in URLs.

On May 31, 2016 7:17:41 PM EDT, Alexis Metaireau notifications@github.com wrote:

No, I'm referring to the hash part, eg https://server/url/#secret

Here I believe 'secret' is not sent to the server


You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/Kinto/formbuilder/issues/89#issuecomment-222849561

Sent from my Android device with K-9 Mail. Please excuse my brevity.

almet commented 8 years ago

So what would be a better way? Would it be possible to derive the keys from the hash rather than relying on local storage?

Natim commented 8 years ago

Would it be possible to derive the keys from the hash rather than relying on local storage?

That's the way 0bin.net works. With this solution the symetric key wil lbe generated on form creation and will be shared across all people A, B and C that will use the same one for a given form (to encrypt as well as to decrypt).

The only benefit of doing that is to prevent people having access to the database to get all forms data. It will not prevent people having access to the form to be able to read the data (but Kinto permission will probably take care of that part).

jvehent commented 8 years ago

It's an imperfect security model because an attacker that wants access to the cleartext can force the server to send javascript that steals the decryption key. You'll only be protecting against cold attacks on the DB, but maybe that's enough for your threat model?

almet commented 8 years ago

So if we have a way to trust the code that's running on the client, then we should be safe. This remembers me of https://blog.notmyidea.org/web-distribution-signing.html but I believe it's orthogonal to what we can do in Kinto directly.

So let's consider this enough for our threat model for now (anyone with access to the client will always have access to the decryption keys in a webapp, I believe)

jvehent commented 8 years ago

The fundamental question is: if users don't trust the people operating the database, why would they trust the same people to keep the javascript safe?

SRI and content signature still place the trust on the operator, not the user.

Lavabit had this exact problem and was being compelled to ship backdoored code to its users. That's why its operator shut it down.

Natim commented 8 years ago

In our case the Kinto server and the formbuilder files are not necessary operated by the same people.

jvehent commented 8 years ago

In which case, the formbuilder can SRI the javascript from kinto, but users still trust the formbuilder to not backdoor the JS. Same concept, with more parties involved.

almet commented 8 years ago

The fundamental question is: if users don't trust the people operating the database, why would they trust the same people to keep the javascript safe?

That's exactly why we want to distribute the clientside in a different way (e.g you can install it locally with debian, which will do a validation check on the files). For instance, it's possible to have a world where form producers and form consumers don't use the same deployment of the software.

To refocus a bit the discussion: the threat model is "you don't trust the people operating the database". We would need to find a way to trust the clients.

Until we have a way to that for the web (I believe it doesn't exist right now, correct me if I'm wrong), solving this issue will go trough other distribution means (e.g. install a software packaged with electron, and signed by its authors / some other people you trust).

almet commented 8 years ago

Also, the design described earlier in this thread prevents the administrators from knowing what's inside the database as they don't have the keys. So, for instance, they cannot give data access to authorities for already existing data (of course, if I'm asked to inject JavaScript on the client, then we're doomed, but well, this is already the case — i.e don't trust SSL).

jvehent commented 8 years ago

For the threat model you're describing, I think your approach is correct. I'd recommending adding that information in the README though.