From fc260b268633901abd2e075103c23ef6acf2ec38 Mon Sep 17 00:00:00 2001 From: tuanaiseo Date: Fri, 3 Apr 2026 19:34:55 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F(frontend)=20room=20ids=20?= =?UTF-8?q?are=20generated=20with=20non-cryptographic=20rand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Room identifiers are created with `Math.random()`, which is predictable and not suitable for security-sensitive identifiers. Predictable room IDs increase the risk of room enumeration and unauthorized access attempts, especially when IDs are part of join URLs. Affected files: generateRoomId.ts Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com> --- CHANGELOG.md | 1 + .../src/features/rooms/utils/generateRoomId.ts | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4d4da66..1488c5e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to - ♻(frontend) standardize role terminology across localizations - 🐛(backend) make start-recording atomic and fault-tolerant +- 🔒️(frontend) room ids are generated with non-cryptographic rand ## [1.15.0] - 2026-04-30 diff --git a/src/frontend/src/features/rooms/utils/generateRoomId.ts b/src/frontend/src/features/rooms/utils/generateRoomId.ts index 6f46734e..097912f6 100644 --- a/src/frontend/src/features/rooms/utils/generateRoomId.ts +++ b/src/frontend/src/features/rooms/utils/generateRoomId.ts @@ -1,10 +1,20 @@ // Google Meet uses only letters in a room identifier const ROOM_ID_ALLOWED_CHARACTERS = 'abcdefghijklmnopqrstuvwxyz' -const getRandomChar = () => - ROOM_ID_ALLOWED_CHARACTERS[ - Math.floor(Math.random() * ROOM_ID_ALLOWED_CHARACTERS.length) +const getRandomChar = () => { + const maxValue = + Math.floor(0x100000000 / ROOM_ID_ALLOWED_CHARACTERS.length) * + ROOM_ID_ALLOWED_CHARACTERS.length + const randomValue = new Uint32Array(1) + + do { + crypto.getRandomValues(randomValue) + } while (randomValue[0] >= maxValue) + + return ROOM_ID_ALLOWED_CHARACTERS[ + randomValue[0] % ROOM_ID_ALLOWED_CHARACTERS.length ] +} const generateSegment = (length: number): string => Array.from(Array(length), getRandomChar).join('')