From 39fbc37dd8f93c1d57d1b2b1fbe8e5feb83d9849 Mon Sep 17 00:00:00 2001 From: drebs Date: Fri, 23 Nov 2018 08:18:03 -0200 Subject: [PATCH] index.html: generate unique pad names Etherpad-lite relies on the user's browser to generate a random pad name, but the current solution is not safe against collisions. In order to generate unique pad names, the following modifications are made: * use a PRNG instead of Math.random() and ensure uniform distribution when selecting chars. * choose the pad name length to achieve a specific number of bits of security. Closes: #3516 --- src/templates/index.html | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/templates/index.html b/src/templates/index.html index 872367c9a..4962560b6 100644 --- a/src/templates/index.html +++ b/src/templates/index.html @@ -187,12 +187,23 @@ function randomPadName() { - var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - var string_length = 10; + // the number of distinct chars (64) is chosen to ensure that + // the selection will be uniform when using the PRNG below + var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; + // the length of the pad name is chosen to get 120-bit security: + // log2(64^20) = 120 + var string_length = 20; + // make room for 8-bit integer values that span from 0 to 255. + var randomarray = new Uint8Array(string_length); + // use browser's PRNG to generate a "unique" sequence + var cryptoObj = window.crypto || window.msCrypto; // for IE 11 + cryptoObj.getRandomValues(randomarray); var randomstring = ''; for (var i = 0; i < string_length; i++) { - var rnum = Math.floor(Math.random() * chars.length); + // instead of writing "Math.floor(randomarray[i]/256*64)" + // we can save some cycles. + var rnum = Math.floor(randomarray[i]/4); randomstring += chars.substring(rnum, rnum + 1); } return randomstring;