commit 3b80d29905596e3cc4a103f136e16800c6d62af5
parent 20b26fc38297ada6c630a5aa9dc826cd618af9a8
Author: Florian Dold <dold@taler.net>
Date: Mon, 20 Jul 2026 20:48:32 +0200
util: never install a constant PRNG in the browser build
loadBrowserPrng installed a source returning the caller's buffer unfilled
whenever self was absent, replacing nacl's throwing default with constant
zero bytes. The browser entry point installs it unconditionally, so this is
reached under SSR, bundler-time evaluation and node tests.
Diffstat:
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/packages/taler-util/src/prng-browser.ts b/packages/taler-util/src/prng-browser.ts
@@ -1,20 +1,20 @@
import { setPRNG } from "./nacl-fast.js";
-/**
- * This only be used when taler util is packaged to run in browser
- * but run in non-browser environment which is common for
- * unit testing. Under this conditions no random is ok.
- */
-const nullRandom = {
- getRandomValues: (c: Uint8Array<ArrayBuffer>) => c,
-};
-
export function loadBrowserPrng() {
- // Initialize PRNG if environment provides CSPRNG.
- // If not, methods calling randombytes will throw.
+ // Only install a PRNG if the environment provides a CSPRNG. Otherwise
+ // leave nacl's throwing default in place: this module is compiled into the
+ // browser entry point and is also reached where `self` does not exist
+ // (SSR, bundler-time evaluation, tests), where a substitute source would
+ // silently yield predictable keys.
+ const glob = globalThis as any;
const cr =
- // @ts-expect-error self is not defined
- typeof self !== "undefined" ? self.crypto || self.msCrypto : nullRandom;
+ typeof glob.self !== "undefined"
+ ? glob.self.crypto || glob.self.msCrypto
+ : undefined;
+
+ if (!cr || typeof cr.getRandomValues !== "function") {
+ return;
+ }
const QUOTA = 65536;
setPRNG(function (x: Uint8Array, n: number) {