From b3db14056481d49544a166d4a3380b676362aaf4 Mon Sep 17 00:00:00 2001 From: YasunoriMATSUOKA Date: Tue, 9 Jun 2026 08:35:54 +0900 Subject: [PATCH 1/2] fix(security): resolve code scanning & Dependabot alerts Code scanning (CodeQL actions/missing-workflow-permissions, 4 alerts): add least-privilege top-level `permissions: contents: read` to the four workflows that lacked one (ci-react, ci-functions, cd-firebase-mainnet, cd-firebase-testnet). They only checkout/build/deploy via FIREBASE_TOKEN, so no write/packages/id-token scopes are needed. Matches pinact.yml. Dependabot (GHSA-w5hq-g745-h8pq uuid <11.1.1, 2 alerts): the vulnerable uuid is transitive via firebase-tools->gaxios@6 (root) and firebase-admin->@google-cloud/*->gaxios/teeny-request (functions). firebase-tools is already at its latest and still pins gaxios@6, and firebase-admin@14 is a breaking major that still pulls vulnerable uuid, so a parent-package bump cannot fix this. Force patched uuid via npm overrides instead: - root: uuid 14.0.0 (also satisfies universal-analytics' ^14 -> clean tree) - functions: uuid 11.1.1 (no ^14 consumer; conservative legacy-11 line) Verified: npm ls uuid clean (exit 0), npm audit 0 vulnerabilities in both packages, root typecheck+build and functions build all pass. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/cd-firebase-mainnet.yml | 3 + .github/workflows/cd-firebase-testnet.yml | 3 + .github/workflows/ci-functions.yml | 3 + .github/workflows/ci-react.yml | 3 + functions/package-lock.json | 96 ++++------------------- functions/package.json | 3 +- package-lock.json | 37 +-------- package.json | 3 + 8 files changed, 38 insertions(+), 113 deletions(-) diff --git a/.github/workflows/cd-firebase-mainnet.yml b/.github/workflows/cd-firebase-mainnet.yml index ae916bf..3ca0d66 100644 --- a/.github/workflows/cd-firebase-mainnet.yml +++ b/.github/workflows/cd-firebase-mainnet.yml @@ -3,6 +3,9 @@ name: CD Firebase mainnet on: workflow_dispatch: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/cd-firebase-testnet.yml b/.github/workflows/cd-firebase-testnet.yml index b8cfb8b..94cd158 100644 --- a/.github/workflows/cd-firebase-testnet.yml +++ b/.github/workflows/cd-firebase-testnet.yml @@ -6,6 +6,9 @@ on: - main workflow_dispatch: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/ci-functions.yml b/.github/workflows/ci-functions.yml index 1a939a3..b6c29a3 100644 --- a/.github/workflows/ci-functions.yml +++ b/.github/workflows/ci-functions.yml @@ -3,6 +3,9 @@ name: CI Functions on: pull_request: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/ci-react.yml b/.github/workflows/ci-react.yml index 80547a2..67b222e 100644 --- a/.github/workflows/ci-react.yml +++ b/.github/workflows/ci-react.yml @@ -3,6 +3,9 @@ name: CI React on: pull_request: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest diff --git a/functions/package-lock.json b/functions/package-lock.json index 6994735..ab5be3b 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -954,21 +954,6 @@ "node": ">=14" } }, - "node_modules/@google-cloud/storage/node_modules/gaxios/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/@google-cloud/storage/node_modules/gcp-metadata": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", @@ -6093,21 +6078,6 @@ "node": ">= 14" } }, - "node_modules/google-gax/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/google-logging-utils": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", @@ -10201,21 +10171,6 @@ "node": ">=14" } }, - "node_modules/teeny-request/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -10653,12 +10608,17 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", "optional": true, "bin": { - "uuid": "dist/bin/uuid" + "uuid": "dist/esm/bin/uuid" } }, "node_modules/v8-to-istanbul": { @@ -11659,7 +11619,7 @@ "p-limit": "^3.0.1", "retry-request": "^7.0.0", "teeny-request": "^9.0.0", - "uuid": "^8.0.0" + "uuid": "11.1.1" }, "dependencies": { "agent-base": { @@ -11678,15 +11638,7 @@ "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^9.0.1" - }, - "dependencies": { - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true - } + "uuid": "11.1.1" } }, "gcp-metadata": { @@ -15225,7 +15177,7 @@ "proto3-json-serializer": "^2.0.2", "protobufjs": "^7.3.2", "retry-request": "^7.0.0", - "uuid": "^9.0.1" + "uuid": "11.1.1" }, "dependencies": { "agent-base": { @@ -15244,7 +15196,7 @@ "https-proxy-agent": "^7.0.1", "is-stream": "^2.0.0", "node-fetch": "^2.6.9", - "uuid": "^9.0.1" + "uuid": "11.1.1" } }, "gcp-metadata": { @@ -15291,12 +15243,6 @@ "agent-base": "^7.1.2", "debug": "4" } - }, - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true } } }, @@ -18098,15 +18044,7 @@ "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.9", "stream-events": "^1.0.5", - "uuid": "^9.0.0" - }, - "dependencies": { - "uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "optional": true - } + "uuid": "11.1.1" } }, "test-exclude": { @@ -18406,9 +18344,9 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "optional": true }, "v8-to-istanbul": { diff --git a/functions/package.json b/functions/package.json index 36bf1cd..4c33485 100644 --- a/functions/package.json +++ b/functions/package.json @@ -43,7 +43,8 @@ "overrides": { "crypto-js": "4.2.0", "axios": "^1.17.0", - "bn.js": "5.2.3" + "bn.js": "5.2.3", + "uuid": "11.1.1" }, "private": true } diff --git a/package-lock.json b/package-lock.json index d58a78c..4dc73ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6903,21 +6903,6 @@ "node": ">=14" } }, - "node_modules/gaxios/node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/gcp-metadata": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", @@ -13303,20 +13288,6 @@ "node": ">=22.0.0" } }, - "node_modules/universal-analytics/node_modules/uuid": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", - "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist-node/bin/uuid" - } - }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -13438,9 +13409,9 @@ } }, "node_modules/uuid": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", - "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -13448,7 +13419,7 @@ ], "license": "MIT", "bin": { - "uuid": "dist/esm/bin/uuid" + "uuid": "dist-node/bin/uuid" } }, "node_modules/valid-url": { diff --git a/package.json b/package.json index 43c36bb..9aeb42b 100644 --- a/package.json +++ b/package.json @@ -64,5 +64,8 @@ "tailwindcss": "^3.4.19", "typescript": "^5.9.3", "vite": "^8.0.16" + }, + "overrides": { + "uuid": "14.0.0" } } From 79133e068b6376af1409f8bf4c7a24754643e29c Mon Sep 17 00:00:00 2001 From: YasunoriMATSUOKA Date: Tue, 9 Jun 2026 08:43:47 +0900 Subject: [PATCH 2/2] fix(security): scope root uuid override to gaxios chain Address Copilot review on #71: the global `uuid: 14.0.0` override forced firebase-tools (which declares uuid ^11.1.1) onto a major beyond its range. Root's only vulnerable uuid is gaxios -> uuid@9.0.1; firebase-tools' direct uuid (11.1.1) and universal-analytics' uuid (14.0.0) are already patched. Scope the override to `gaxios -> uuid: 11.1.1` so only the vulnerable chain moves, every package stays within its declared range, and npm ls is clean (no ELSPROBLEMS). functions keeps its flat 11.1.1 override since all its uuid instances are vulnerable and 11.1.1 is the minimum patched version. Verified: npm ci exit 0, npm ls uuid clean (exit 0), npm audit 0 vulnerabilities, typecheck + build pass. Co-Authored-By: Claude Opus 4.8 (1M context) --- package-lock.json | 28 ++++++++++++++++++++++++++++ package.json | 4 +++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 4dc73ef..4d9132d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6649,6 +6649,20 @@ "node": "*" } }, + "node_modules/firebase-tools/node_modules/uuid": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/firebase/node_modules/@firebase/auth": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.13.2.tgz", @@ -6903,6 +6917,20 @@ "node": ">=14" } }, + "node_modules/gaxios/node_modules/uuid": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/gcp-metadata": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", diff --git a/package.json b/package.json index 9aeb42b..af01e72 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,8 @@ "vite": "^8.0.16" }, "overrides": { - "uuid": "14.0.0" + "gaxios": { + "uuid": "11.1.1" + } } }