From c9f36449884c887d6dd5443e3f44ccdd9f5e38e8 Mon Sep 17 00:00:00 2001 From: Jonas Wagner Date: Sun, 15 May 2022 22:13:07 +0200 Subject: [PATCH] Better random (#213) * randomString: generate a securely random string. Also, support lengths > 12 in case that's ever needed. This is used in at least one case (creating device tokens for users) where it seems important that the output is unpredictable. * Try harder to create unique usernames. The previous version added 16 bits of entropy to the username, which isn't all that much. Due to the birthday paradox, it would be enough to create ~256 users with the same prefix to get a collision. Trying that would probably fail later on, and not create security issues... but it just seems better to be on the safe side here. --- common/util/random.ts | 12 ++++++++---- functions/src/create-user.ts | 3 +-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/common/util/random.ts b/common/util/random.ts index f52294f1..3026dcde 100644 --- a/common/util/random.ts +++ b/common/util/random.ts @@ -1,7 +1,11 @@ -export const randomString = (length = 12) => - Math.random() - .toString(16) - .substring(2, length + 2) +// Returns a cryptographically random hexadecimal string of length `length` +// (thus containing 4*`length` bits of entropy). +export const randomString = (length = 12) => { + const bytes = new Uint8Array(Math.ceil(length / 2)) + crypto.getRandomValues(bytes) + const hex = bytes.reduce((s, b) => s + ('0' + b.toString(16)).slice(-2), '') + return hex.substring(0, length) +} export function genHash(str: string) { // xmur3 diff --git a/functions/src/create-user.ts b/functions/src/create-user.ts index f73b868b..fdbb0edd 100644 --- a/functions/src/create-user.ts +++ b/functions/src/create-user.ts @@ -42,8 +42,7 @@ export const createUser = functions const name = cleanDisplayName(rawName) let username = cleanUsername(name) - const sameNameUser = await getUserByUsername(username) - if (sameNameUser) { + while (await getUserByUsername(username)) { username += randomString(4) }