dedis / d-voting

📧 E-Voting platform based on the Dela blockchain
https://dedis.github.io/d-voting
BSD 3-Clause "New" or "Revised" License
18 stars 7 forks source link

THREAT - A user can vote multiple times (count as multiple votes) in an election. #248

Open chenchanglew opened 1 year ago

chenchanglew commented 1 year ago

Scenario

Whenever the frontend sends an encrypted ballot to the backend to sign, the backend will include the userID of the user in the ballot and sign the msg. This design will allow every user to vote at most once. However, since we are using Tequila as our login server, thus it is hard to create multiple valid users in Tequila during backend testing. A workaround was created. Backend implements a function called “makeID” to create a random ID and sign it along with the encrypted ballot. This will allow a user to vote multiple times which counts as multiple votes. And this function is not yet removed until now. Thus an adversary can vote as many times as he wants to manipulate the election results.

Source

In the file “web/backend/Server.ts” function app.use(‘/api/evoting/*’)

app.use('/api/evoting/*', (req, res) => {
. . . 
// special case for voting
  const regex = /\/api\/evoting\/elections\/.*\/vote/;
  if (req.baseUrl.match(regex)) {
    // We must set the UserID to know who this ballot is associated to. This is
    // only needed to allow users to cast multiple ballots, where only the last
    // ballot is taken into account. To preserve anonymity the web-backend could
    // translate UserIDs to another random ID.
    // bodyData.UserID = req.session.userid.toString();
    bodyData.UserID = makeid(10);
  }

function makeid(length: number) {
  let result = '';
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const charactersLength = characters.length;
  for (let i = 0; i < length; i += 1) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength));
  }
  return result;
}

Breaking Property

Availability, Auditability

Risk

CVSS score: 6.5/10

Mitigation

Remove the makeId function. If the developer prefers to keep the function for testing, we can set an env variable in config.env to determine this environment, which production environment would use User Id and the Dev environment would use Fake Id.

PascalinDe commented 1 year ago

@pierluca we had been discussing the need for a sort of testing environment as well, and I think that the solution that @chenchanglew proposes is a good approach

ineiti commented 1 year ago

Perhaps we can put something like https://create-react-app.dev/docs/adding-custom-environment-variables/ in the code so it automatically chooses the debugging feature or not. Even though I did not completely understand whether NODE_ENV would serve our needs here.

pierluca commented 1 year ago

I think indeed NODE_ENV could be the right approach here. That's what I've used in other projects and it makes things rather simple.

ineiti commented 1 year ago

I think indeed NODE_ENV could be the right approach here.

Currently we took the even simpler approach of adding a console.warn("DEBUG code")