From 7b8618412f7ae9f1725774ea72a15a7beebdcee7 Mon Sep 17 00:00:00 2001 From: kyungseopk1m Date: Tue, 14 Apr 2026 15:50:55 +0900 Subject: [PATCH] fix(app): replace node-forge with native crypto for private key validation Replace the node-forge dependency with Node.js built-in crypto module for validating PEM-formatted private keys in ServiceAccount. This eliminates Math.random() calls during initializeApp(), which caused errors in environments that restrict non-deterministic APIs such as Next.js React Server Components with PPR/SSG. Fixes #3075 --- package-lock.json | 14 ++------------ package.json | 1 - src/app/credential-internal.ts | 5 ++--- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60f5453fbc..3cbdbdbbb6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "firebase-admin", - "version": "13.7.0", + "version": "13.8.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "firebase-admin", - "version": "13.7.0", + "version": "13.8.0", "license": "Apache-2.0", "dependencies": { "@fastify/busboy": "^3.0.0", @@ -17,7 +17,6 @@ "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", - "node-forge": "^1.4.0", "uuid": "^11.0.2" }, "devDependencies": { @@ -8875,15 +8874,6 @@ } } }, - "node_modules/node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", diff --git a/package.json b/package.json index f375c597e6..87dc2b7c5d 100644 --- a/package.json +++ b/package.json @@ -222,7 +222,6 @@ "google-auth-library": "^10.6.1", "jsonwebtoken": "^9.0.0", "jwks-rsa": "^3.1.0", - "node-forge": "^1.4.0", "uuid": "^11.0.2" }, "optionalDependencies": { diff --git a/src/app/credential-internal.ts b/src/app/credential-internal.ts index 8ce61b4edd..1dbe7ecb80 100644 --- a/src/app/credential-internal.ts +++ b/src/app/credential-internal.ts @@ -16,6 +16,7 @@ */ import fs = require('fs'); +import { createPrivateKey } from 'crypto'; import { Credentials as GoogleAuthCredentials, GoogleAuth, Compute, AnyAuthClient } from 'google-auth-library' import { Agent } from 'http'; @@ -214,10 +215,8 @@ class ServiceAccount { throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, errorMessage); } - // eslint-disable-next-line @typescript-eslint/no-var-requires - const forge = require('node-forge'); try { - forge.pki.privateKeyFromPem(this.privateKey); + createPrivateKey(this.privateKey); } catch (error) { throw new FirebaseAppError( AppErrorCodes.INVALID_CREDENTIAL,