From 46b1434d6d8a13e7e345002751eda3c55d65ea25 Mon Sep 17 00:00:00 2001 From: MP2EZ <182439403+MP2EZ@users.noreply.github.com> Date: Sun, 26 Jul 2026 03:03:41 -0700 Subject: [PATCH] chore: INFRA-312 record audit-gate triage note (outage was transient, no fix needed) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Security + compliance gate failed repo-wide for roughly an hour with zero repo changes, blocking every PR including INFRA-306's otherwise-green #221. It then RECOVERED ON ITS OWN: an untouched `development` worktree went from failing to "Passed npm security audit" with no edit of any kind, same node_modules, same lockfile. So there is nothing to fix in this repo, and this commit deliberately changes no CI config and no allowlist entry. It adds only a triage note, because the thing that actually cost the time was a useless error message. What happened: npm's legacy /-/npm/v1/security/audits/quick endpoint answered `400 Bad Request - Invalid package tree` for this ~1,185-package tree while auditing a 20-package control tree fine, and the newer security/advisories/bulk endpoint returned an undecompressed gzip body. audit-ci surfaced all of it as the bare, unactionable `code undefined:`. Eight hypotheses were tested and disproved (full ledger on the INFRA-312 Notion item). The one never tried was "wait longer" — a `gh run rerun --failed` about 30 minutes in still failed, which made the outage look permanent. The note therefore records the retry window explicitly, plus the two most attractive red herrings: npm's own "rebuild your package-lock.json" hint (the lockfile was byte-identical and structurally clean — 0 missing versions, 0 link:true, 0 non-numeric versions), and pinning a newer npm to reach the bulk endpoint (attempted in the since-closed PR #222; npm 11.18.0 was confirmed active in CI and failed identically). Verified the gate is healthy rather than merely quiet — a gate that passes because it stopped auditing is the failure class MAINT-307 and INFRA-306 both had to clean up. Dropping GHSA-mh99-v99m-4gvg from a scratch copy of the allowlist makes audit-ci exit 1 and print the advisory with its full dependency paths. Co-Authored-By: Claude Opus 5 (1M context) --- app/.audit-ci.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/.audit-ci.json b/app/.audit-ci.json index 4f1b1338..8d7ec345 100644 --- a/app/.audit-ci.json +++ b/app/.audit-ci.json @@ -13,5 +13,5 @@ "GHSA-v245-v573-v5vm", "GHSA-mh99-v99m-4gvg" ], - "$comment": "MAINT-182. First three CVEs are transitive through @expo/config-plugins@56.0.8 (build-time only, no patched stable available as of 2026-05-27). GHSA-ph9p (tmp path traversal) and GHSA-6vfc (markdown-it ReDoS) only run during prebuild/codegen. GHSA-w5hq (uuid buffer bounds) is in dev tooling. Review when Expo ships @expo/config-plugins >=56.0.9 stable: drop these GHSAs and verify `npm audit --audit-level moderate` passes. --- MAINT-281 (2026-06-15) added the last two (both quadratic-complexity DoS, no fix in range, require attacker-controlled input which Being has no path for): GHSA-h67p (js-yaml) is dev/build-time ONLY — transitive via ts-jest, @expo/cli/@expo/xcpretty, and babel-jest; fix is a breaking ts-jest major bump. GHSA-6v5v (markdown-it) is runtime via react-native-markdown-display@7, but its ONLY call site renders bundled first-party legal docs (LegalDocumentScreen <- legalContent.generated.ts <- docs/legal/*.md) — no remote/user markdown, so the DoS is unreachable; no patched markdown-it in react-native-markdown-display@7's range. Drop GHSA-6v5v if react-native-markdown-display upgrades markdown-it; drop GHSA-h67p on the next ts-jest major. The high-severity form-data CVE (GHSA-hmw2-7cc7-3qxx) disclosed the same day was FIXED via lockfile (npm audit fix), not allowlisted. --- MAINT-294 (2026-07-08) added GHSA-22p9-wv53-3rq4 (linkify-it 'LinkifyIt#match' scan loop, quadratic-complexity ReDoS, high; range <=5.0.0, fixAvailable:false). Direct twin of GHSA-6v5v: transitive via react-native-markdown-display@7 -> markdown-it@10 -> linkify-it@2.2.0, and its ONLY call site is LegalDocumentScreen rendering bundled first-party legal docs (legalContent.generated.ts <- docs/legal/*.md) — no remote/user markdown, so the quadratic blow-up needs attacker-controlled input Being has no path to. No fix in range (would need breaking markdown-it/react-native-markdown-display majors, risking the expo-modules-jsi@56.0.7 patch pin). Drop GHSA-22p9 together with GHSA-6v5v when react-native-markdown-display upgrades markdown-it/linkify-it past the vulnerable range. --- INFRA-302 (2026-07-21) three new HIGH DoS advisories published to the GitHub DB. Two were FIXED via same-major overrides (not allowlisted): GHSA-395f-4hp3-45gv (shell-quote quadratic parse() DoS) -> shell-quote ^1.10.0 (was 1.8.4, single copy); GHSA-3jxr-9vmj-r5cp (brace-expansion exponential expansion DoS) -> version-keyed overrides pinning the 1.x eslint/jest tooling copies to 1.1.16 and the 5.x copy to 5.0.7. The THIRD, GHSA-52cp-r559-cp3m (js-yaml quadratic merge-key DoS; range <=3.14.2 || 4.0.0-4.2.0, fixAvailable but not in-range for the 3.x path), is allowlisted here as a direct sibling of the already-allowlisted GHSA-h67p (js-yaml, MAINT-281): the top-level js-yaml@3.14.2 consumer has NO same-major fix (all 3.x is vulnerable) and the single GHSA covers both the 3.x and 4.x paths, so a clean override is impossible without a breaking 3->4 major bump of a dev/build-time tooling dep (ts-jest, @expo/cli/@expo/xcpretty, eslintrc, babel-jest). Dev/build-time only, operates on trusted first-party source, no attacker-controlled-input path -> unreachable DoS. Drop GHSA-52cp together with GHSA-h67p on the next ts-jest major (both js-yaml). Also allowlisted GHSA-v245-v573-v5vm (linkify-it, published same window) as a direct sibling of GHSA-22p9/GHSA-6v5v: transitive via react-native-markdown-display@7 -> markdown-it@10 -> linkify-it, whose ONLY call site renders bundled first-party legal docs (LegalDocumentScreen <- legalContent.generated.ts <- docs/legal/*.md) — no remote/user markdown, so unreachable; no fix in range without breaking markdown-it/react-native-markdown-display majors (risks the expo-modules-jsi@56.0.7 patch pin). Drop GHSA-v245 with GHSA-22p9/GHSA-6v5v when react-native-markdown-display upgrades markdown-it/linkify-it past the vulnerable range. --- FEAT-301 (2026-07-25) a NEW brace-expansion advisory GHSA-mh99-v99m-4gvg (unbounded-expansion OOM DoS; range <=5.0.7, HIGH) landed on the exact versions INFRA-302 pinned. The 5.x line (minimatch@10) is bumped to 5.0.8 via overrides (same-major fix). The 1.x line (minimatch@3 under eslint/jest tooling) has NO same-major fix — 1.1.16 is the newest 1.x and is still <=5.0.7, and npm's only offered 'fix' is a breaking jest major downgrade — and the single GHSA covers both the 1.x and 5.x paths, so it is allowlisted here. brace-expansion is transitive via minimatch/glob (Node filesystem tooling), NEVER bundled into the RN runtime, and operates on trusted first-party glob patterns during dev/build/lint/test — no attacker-controlled-input path, so the DoS is unreachable. Drop GHSA-mh99 when the eslint/jest tooling upgrades minimatch@3 -> a brace-expansion line with a >5.0.7 backport (or the 1.x consumers are gone)." + "$comment": "MAINT-182. First three CVEs are transitive through @expo/config-plugins@56.0.8 (build-time only, no patched stable available as of 2026-05-27). GHSA-ph9p (tmp path traversal) and GHSA-6vfc (markdown-it ReDoS) only run during prebuild/codegen. GHSA-w5hq (uuid buffer bounds) is in dev tooling. Review when Expo ships @expo/config-plugins >=56.0.9 stable: drop these GHSAs and verify `npm audit --audit-level moderate` passes. --- MAINT-281 (2026-06-15) added the last two (both quadratic-complexity DoS, no fix in range, require attacker-controlled input which Being has no path for): GHSA-h67p (js-yaml) is dev/build-time ONLY \u2014 transitive via ts-jest, @expo/cli/@expo/xcpretty, and babel-jest; fix is a breaking ts-jest major bump. GHSA-6v5v (markdown-it) is runtime via react-native-markdown-display@7, but its ONLY call site renders bundled first-party legal docs (LegalDocumentScreen <- legalContent.generated.ts <- docs/legal/*.md) \u2014 no remote/user markdown, so the DoS is unreachable; no patched markdown-it in react-native-markdown-display@7's range. Drop GHSA-6v5v if react-native-markdown-display upgrades markdown-it; drop GHSA-h67p on the next ts-jest major. The high-severity form-data CVE (GHSA-hmw2-7cc7-3qxx) disclosed the same day was FIXED via lockfile (npm audit fix), not allowlisted. --- MAINT-294 (2026-07-08) added GHSA-22p9-wv53-3rq4 (linkify-it 'LinkifyIt#match' scan loop, quadratic-complexity ReDoS, high; range <=5.0.0, fixAvailable:false). Direct twin of GHSA-6v5v: transitive via react-native-markdown-display@7 -> markdown-it@10 -> linkify-it@2.2.0, and its ONLY call site is LegalDocumentScreen rendering bundled first-party legal docs (legalContent.generated.ts <- docs/legal/*.md) \u2014 no remote/user markdown, so the quadratic blow-up needs attacker-controlled input Being has no path to. No fix in range (would need breaking markdown-it/react-native-markdown-display majors, risking the expo-modules-jsi@56.0.7 patch pin). Drop GHSA-22p9 together with GHSA-6v5v when react-native-markdown-display upgrades markdown-it/linkify-it past the vulnerable range. --- INFRA-302 (2026-07-21) three new HIGH DoS advisories published to the GitHub DB. Two were FIXED via same-major overrides (not allowlisted): GHSA-395f-4hp3-45gv (shell-quote quadratic parse() DoS) -> shell-quote ^1.10.0 (was 1.8.4, single copy); GHSA-3jxr-9vmj-r5cp (brace-expansion exponential expansion DoS) -> version-keyed overrides pinning the 1.x eslint/jest tooling copies to 1.1.16 and the 5.x copy to 5.0.7. The THIRD, GHSA-52cp-r559-cp3m (js-yaml quadratic merge-key DoS; range <=3.14.2 || 4.0.0-4.2.0, fixAvailable but not in-range for the 3.x path), is allowlisted here as a direct sibling of the already-allowlisted GHSA-h67p (js-yaml, MAINT-281): the top-level js-yaml@3.14.2 consumer has NO same-major fix (all 3.x is vulnerable) and the single GHSA covers both the 3.x and 4.x paths, so a clean override is impossible without a breaking 3->4 major bump of a dev/build-time tooling dep (ts-jest, @expo/cli/@expo/xcpretty, eslintrc, babel-jest). Dev/build-time only, operates on trusted first-party source, no attacker-controlled-input path -> unreachable DoS. Drop GHSA-52cp together with GHSA-h67p on the next ts-jest major (both js-yaml). Also allowlisted GHSA-v245-v573-v5vm (linkify-it, published same window) as a direct sibling of GHSA-22p9/GHSA-6v5v: transitive via react-native-markdown-display@7 -> markdown-it@10 -> linkify-it, whose ONLY call site renders bundled first-party legal docs (LegalDocumentScreen <- legalContent.generated.ts <- docs/legal/*.md) \u2014 no remote/user markdown, so unreachable; no fix in range without breaking markdown-it/react-native-markdown-display majors (risks the expo-modules-jsi@56.0.7 patch pin). Drop GHSA-v245 with GHSA-22p9/GHSA-6v5v when react-native-markdown-display upgrades markdown-it/linkify-it past the vulnerable range. --- FEAT-301 (2026-07-25) a NEW brace-expansion advisory GHSA-mh99-v99m-4gvg (unbounded-expansion OOM DoS; range <=5.0.7, HIGH) landed on the exact versions INFRA-302 pinned. The 5.x line (minimatch@10) is bumped to 5.0.8 via overrides (same-major fix). The 1.x line (minimatch@3 under eslint/jest tooling) has NO same-major fix \u2014 1.1.16 is the newest 1.x and is still <=5.0.7, and npm's only offered 'fix' is a breaking jest major downgrade \u2014 and the single GHSA covers both the 1.x and 5.x paths, so it is allowlisted here. brace-expansion is transitive via minimatch/glob (Node filesystem tooling), NEVER bundled into the RN runtime, and operates on trusted first-party glob patterns during dev/build/lint/test \u2014 no attacker-controlled-input path, so the DoS is unreachable. Drop GHSA-mh99 when the eslint/jest tooling upgrades minimatch@3 -> a brace-expansion line with a >5.0.7 backport (or the 1.x consumers are gone). --- INFRA-312 (2026-07-26) TRIAGE NOTE, no allowlist change. If this gate fails with the bare message `code undefined:` and nothing else, that is audit-ci failing to CLASSIFY an error from npm \u2014 it is NOT a CVE finding. A real finding always names its GHSA and prints the dependency path. Do not theorise from `code undefined:`; run the underlying command directly and read what npm actually says: `cd app && npm audit --audit-level moderate`. FIRST OCCURRENCE was a TRANSIENT npm REGISTRY INCIDENT, not a repo problem. For roughly an hour npm's legacy `/-/npm/v1/security/audits/quick` endpoint answered `400 Bad Request \u2014 Invalid package tree` for this ~1,185-package tree while happily auditing a 20-package control tree, and the newer `security/advisories/bulk` endpoint returned an undecompressed (gzip) body. It blocked every PR in the repo with zero repo changes, then recovered on its own: an untouched `development` worktree went from failing to `Passed npm security audit` with no edit of any kind. LESSON \u2014 the retry window matters. A `gh run rerun --failed` ~30 min in still failed, which made the outage look permanent and sent the investigation through eight hypotheses (all recorded on INFRA-312). Before changing ANYTHING here, re-run the audit against a clean worktree and wait longer than half an hour. Two specific red herrings to skip: npm's own 'run npm install to rebuild your package-lock.json' hint (the lockfile was byte-identical and structurally clean), and pinning a newer npm for the bulk endpoint (tried in the since-closed PR #222 \u2014 npm 11.18.0 was confirmed active in CI and failed identically)." }