From 55983b11df9826964db614b71dd7bd2a7b7c3e16 Mon Sep 17 00:00:00 2001 From: marcin2121 <13873718+marcin2121@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:30:50 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20fix(spin-wheel):=20replace=20ins?= =?UTF-8?q?ecure=20Math.random()=20with=20Web=20Crypto=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced `Math.random()` with `crypto.getRandomValues()` for both selecting the prize and generating the coupon code suffix. - This mitigates the vulnerability of predictable PRNG outputs in the spin wheel action, protecting user coupon codes from being guessed. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- app/actions/spin-wheel.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/app/actions/spin-wheel.ts b/app/actions/spin-wheel.ts index ef2d6ad..d6872e9 100644 --- a/app/actions/spin-wheel.ts +++ b/app/actions/spin-wheel.ts @@ -59,7 +59,14 @@ export async function spinWheel() { // 4. ALGORYTM LOSOWANIA (Ważony) z puli tylko dostępnych nagród const totalWeight = availablePrizes.reduce((sum: number, p: any) => sum + Number(p.chance), 0) - let randomNum = Math.random() * totalWeight + + // Używamy bezpiecznego generatora liczb losowych zamiast Math.random() + const cryptoRandomBuffer = new Uint32Array(1); + crypto.getRandomValues(cryptoRandomBuffer); + // Przekształcamy uint32 (0 do 0xFFFFFFFF) na float [0, 1) + const secureRandomFloat = cryptoRandomBuffer[0] / (0xFFFFFFFF + 1); + + let randomNum = secureRandomFloat * totalWeight; let winningPrize = availablePrizes[0] for (const prize of availablePrizes) { @@ -71,7 +78,16 @@ export async function spinWheel() { } // 5. Generujemy unikalny kod kuponu (np. BONUS10-A4B9) - const randomSuffix = Math.random().toString(36).substring(2, 6).toUpperCase() + // Bezpieczne generowanie 4 znaków z bazy 36 (A-Z, 0-9) + const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + const suffixBuffer = new Uint8Array(4); + crypto.getRandomValues(suffixBuffer); + + let randomSuffix = ''; + for (let i = 0; i < 4; i++) { + randomSuffix += charset[suffixBuffer[i] % charset.length]; + } + const finalCode = `${winningPrize.code_prefix}-${randomSuffix}` // 6. Zapisujemy wylosowany kupon dla użytkownika