benadida / helios-server

Helios server

Home Page:http://heliosvoting.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Client-side implementation of voting and trustee key operations to avoid having to trust the server

redfast00 opened this issue · comments

Because of the COVID-19 pandemic, we used Helios (with some patches to use our own auth provider and to run Helios in docker, see https://github.com/ZeusWPI/helios-server/tree/add/docker-support) to run the elections of our computer science student association. One of the feedback points we got from our members was that while the server code is open source, it's pretty much impossible for voters to verify that the JavaScript that is served from the server to do cryptography is the same code that is published on GitHub and that there is no secret backdoor added that for example logs your vote before encrypting it in the browser. This is particularly bad in our case, since systems administrator is an elected position, so they're not in a neutral position (everyone trusts our systems administrators, but it would be nice if that trust were not needed).

To enable voters to audit their voting software, a local client that interacts with the server via an API is needed. Users can then choose between using the web version or using their own local client. I imagine that a lot of the Python or JavaScript code can be reused when writing this client.

Another point is that both key-generation and decryption for the trustees happens in-browser, which makes it easy for a rogue sysadmin to steal the key by again modifying the JavaScript that is served from the server. Here it would also be nice if the trustees could generate their own keys and do the decryption locally.

There appears to already be a project (https://github.com/google/pyrios) to verify elections locally, but this does not do voting or trustee cryptography.

This year, somewhen in May, we'll hold elections again. The COVID-19 situation doesn't look too hopeful, so I think we'll be using Helios again. It would be really nice if that feature were implemented before then (I have no expectations though, if it's not implemented, so be it; I'm already really grateful that Helios was created and that it is opensource).

Hi @redfast00, thanks for posting this issue.

My sense is that the benefit of a client executable for ballot casting would be small, while the cost would be high, so I wouldn't recommend building one / relying on one. I could see a slightly better benefit/cost ratio for trustee keys, but I'm still not sure it's the right tradeoff.

Specifically, on ballot casting: this would make changing the code / updating the system a good bit harder over time, while it's not clear that most users would know how to check that they got the right client-side executable (not to mention the increased risk of running a client-side executable.)

On key generation: that's more limited functionality and could be more useful, but again the cost would be high, and remember that the compromise of a trustee key means a privacy compromise, not a correctness of tabulation compromise.

So overall, I don't think this is the right tradeoff.

My sense is that the benefit of a client executable for ballot casting would be small, while the cost would be high, so I wouldn't recommend building one / relying on one. I could see a slightly better benefit/cost ratio for trustee keys, but I'm still not sure it's the right tradeoff.

The benefit of building a client executable is that users don't have to trust the Helios server administrator for their privacy. I think this benefit is rather large, since this is what sets Helios apart from other, non-cryptographic voting systems (privacy-wise, that is). The cost might not be as big as you think: if you have an API, a lot of the JavaScript code can be shared with the web client and a native client (if it is written in NodeJS). All of this is completely optional for users: they can choose whether to use the web client or the native client.

Specifically, on ballot casting: this would make changing the code / updating the system a good bit harder over time, while it's not clear that most users would know how to check that they got the right client-side executable (not to mention the increased risk of running a client-side executable.)

This can be solved with a simple version check in the API. This version gets bumped every time the API changes. The native client would mainly be used by more technical users, so if they get an error message that their client is outdated, they can just fetch the new code from upstream (and audit it). Most users don't have to check that they have the right client-side executable, since most (non-technical) users probably won't use the executable but use the web version instead. I envision it as a simple command-line-interface, so there doesn't need to be a lot of code for the UI.

On key generation: that's more limited functionality and could be more useful, but again the cost would be high, and remember that the compromise of a trustee key means a privacy compromise, not a correctness of tabulation compromise.

In the current system, privacy-wise, there is basically no protection against a rogue server admin while holding the elections. It's like possibly having a person standing next to you while you are voting, or in the case of the trustees, a person being able to see what every person has voted. The Helios cryptographic design makes it possible to also defend against rogue systems administrators peeking at votes, but because of the implementation, this protection doesn't currently exist.

I don't really know how it's currently implemented in Helios. Is there an API to get and submit the data (so a third party could write their own tool that interacts with Helios without using the web client)? I assume that we would then also need to be able to get a token for the command-line tool to authenticate with after authentication in the web UI.

I see the workflow for the native client as follows:

  1. User authenticates on the web site
  2. After authentication, user has a possibility to show and copy a URL that points to this election and has a token that authenticates them in it.
  3. User uses the tool to fetch who they can vote on
  4. User writes who they vote on in a file
  5. User passes this file to the voting tool, the tool checks that this is a valid vote, encrypts it and sends it to the server (the checking step not for security, but to prevent typo's and such)

For trustees, the same workflow, but with a key being saved to a local file.

In Belenios, which is inspired by Helios, but has evolved differently since 2012, there is a command-line tool to perform all cryptographic operations without trusting the server. Most of the code (written in OCaml) is shared between the web client and the CLI. Moreover, it is possible to compile the web client locally and use it to submit an encrypted ballot to a running server.

@glondu Thanks you! We'll switch to Belenios this year then. I saw that there's a docker environment already, so that will make porting our docker-compose.yml file easier. The only thing we'll then need to do is hack in our own authentication system, but this probably won't be that hard since it's just oauth.

@redfast00 I don't agree with your analysis of the cost – In my experience, maintaing a client-side executable and securing it is quite hard. I also don't see how individuals can trust that executable: will individuals be rebuilding it from source? Unlikely.

So, I'm having trouble seeing a threat model that makes a real difference for real users other than a couple of particularly advanced users who might build the client executable from scratch.

That said, if Belenios is a better fit, that's great!

I should add one important thing: it is, in my opinion, a common mistake to equate "the ability for the server to modify source code and ship an evil binary / JavaScript bundle" with "the ability to read votes out of a database." I think there is a very large difference in practice between those two. The former requires planning and risks detection. If caught, it is very hard to deny. It's very different from someone perusing a database of cast votes.

Helios protects against the database of cast votes. It doesn't protect against an evil server willing to deliver corrupt code, but, as I've explained before, I am hard-pressed to see how protecting against that threat for typical users is doable in a remote voting setting.

Cheers!