Skip to content

E2EE on LiberaForms: first implementation

End to End Encryption (E2EE), that is, allowing form Editors to ensure that the answers to their forms, cannot be read even by their friendly sysadmins, has been on the roadmap of LiberaForms since we received the European Comission's Next Generation Internet initiative NLnet grant in 2023.

We are happy to share a preview of the first implementation of this feature!

We have deliberated about how to implement this feature and some of its pros and cons, and after many ramblings we got to it.

Proof of Concept phase

In the collaborating spirit of NLnet, it was suggested that we try out the OpenPGP.js library:

[OpenPGP.js provides] an Open Source OpenPGP library in JavaScript so it can be used on virtually every device

And they deliver.

This is what we used to get acquainted with the library, its concepts and to validate our expectations of the implementation.

Albeit very simple and lacking in style, we found it very useful, feel free to re-use, adapt and improve upon it.

The main advantage though, was reading the documentation, getting familiar with the library and gaining first-hand experience of possible caveats: like dealing with binary vs string data, which JavaScript didn't do wonderfully until somewhat recently, and OpenPGP.js treats very reasonably.

Planning phase

After having a basic isolated proof of concept for the cryptographical bits, we started planning the work by subdividing tasks and identifying expected pain points and dependencies.

We did this on a Forgejo instance run by eXO.cat, who kindly provide LiberaForm's CI.

The project is public though, until Forge Federation is fully implemented you can't really interact with it (that's what our GitLab account is for). This is how it looks like right now:

Kanban showing the E2EE project development

The first implementation

So, with enough background and context, this is what the first implementation looks like.

Editor and user experience

The previous videos show.... very normal-looking form submission and answer querying workflows. Maybe even... too Normal?

Well, our data-display vuejs component was, in part, developed with this encryption feature in mind by fully handling form answers on the client.

But also, in order to bring the first iteration forward quickly, we decided to simplify certain things, amongst them:

Encryption keys cannot be currently password-protected

We plan on overcoming this limitation in the upcoming final stage, but this is the reason why it is all seamless! See below for an explanation.

The database

In fact, this is what the database shows:

liberaforms=# select * from answers;
 id |          created           | updated | form_id | author_id | marked |              data              | public_id
----+----------------------------+---------+---------+-----------+--------+--------------------------------+----------
 74 | 2024-08-05 01:56:30.910863 |         |       7 |         1 | f      | {"e2ee-answer": "wV4[...]Gm8"} |
(1 row)

The data only contains an e2ee-answer base64-encoded blob! And that base64-encoded blob is the binary representation of the submitted answer, after encrypting it with the form key!

Behind the scenes

What is happening behind the scenes is:

  • the Editor generates an account OpenPGP key (asymmetric, ECC) in the browser
  • this OpenPGP private key is saved in local storage, and the Editor can back it up and restore it
  • only the public key of the Editor is persisted on the server
  • the Editor activates E2EE for the Form
  • when the public Form is served to an end User, they get the public key of the editor
  • using that public key, the browser encrypts all form data before sending it to the server
  • the same thing happens with attachments
  • the server never sees a User's answers or attachments (though file names are known to the server)
  • When the Editor wants to see a Form's answers, their private key is loaded from local storage, and all data is decrypted locally on the fly
  • Similarly, when an Editor wants to download an attachment: it first gets downloaded in an encrypted fashion, and decrypted in the browser

So, all in all, as long as an Editor doesn't use multiple devices, the User eXperience is the same as without E2EE...

Well, nearly. There are some limitations.

Limitations

We are in the process of documenting them (see this and this), and there might be more, we'll solve as many as possible before releasing the feature; but these are the highlights:

  • Password-protected encryption keys are not really supported
  • Sharing a form's encrypted answers is unsupported at this stage
  • It is way too easy to replace an editor's keys, losing all answers!
  • The E2EE key management UI is a bit quirky

How can I have a sneak preview?

Just remember not to use this version and feature on any instance where you care about your data, we will work with this assumption when adapting database migrations between this unreleased version and the first released version that implements E2EE.

With that disclaimer out of the way: you just install/upgrade LiberaForms as usual, except you do it against the develop branch at farga.eXO.cat.

Everything else stays the same!

If you do try this out, let us know, but keep in mind we'll be finishing this in a very short time-frame!

What's next here?

Well, first goal is to restore form answer sharing on E2EE Forms.

And finally after that, all the other limitations we mention here, which affect data security directly by not providing enough warnings/safe-guards on operations that could imply data loss. Not to mention all issues and possible improvements we can detect during testing.

On release, LiberaForms will have this feature enabled but not as a default. Editors will be able to enable it at their own risk, and Server Admins will be able to disable the feature, make it a default, or force it on their server.

Let us know how this looks to you, your feedback is very appreciated!