Skip to content

Commit 1697383

Browse files
authored
Merge pull request #70 from aws-samples/chore/frontend-audit-hygiene
audit frontend dependencies in CI and patch nanoid
2 parents 6b03a8c + cac8acb commit 1697383

4 files changed

Lines changed: 51 additions & 41 deletions

File tree

.github/workflows/ci.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,21 @@ jobs:
267267
- uses: actions/setup-node@v5
268268
with:
269269
node-version: ${{ env.NODE_VERSION }}
270+
cache: npm
271+
cache-dependency-path: |
272+
package-lock.json
273+
frontend/package-lock.json
270274
271275
- name: Install workspaces (root lockfile)
272276
run: npm ci
273277

274278
- name: Audit dependencies (blocking, with justified allowlist)
275279
run: npx audit-ci --config .audit-ci.json
280+
281+
- name: Install frontend deps (frontend lockfile)
282+
run: npm ci
283+
working-directory: frontend
284+
285+
- name: Audit frontend dependencies (blocking, with justified allowlist)
286+
run: npx audit-ci --config .audit-ci.json
287+
working-directory: frontend

audit-ci-allowlist-justifications.md

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -86,41 +86,28 @@ bypass-successor (mh99's mitigation covers `<5.0.8`; rgw5 extends the vulnerable
8686
3. Re-run `npm audit` to confirm no new unallowlisted advisories land.
8787

8888

89-
## GHSA-qwww-vcr4-c8h2 — react-router (HIGH RSC Mode CSRF Bypass Allows Action Execution Before 400 Response)
90-
91-
**Affected instances:**
92-
- `frontend/node_modules/react-router@7.18.1` (transitive via react-router-dom)
93-
- `frontend/node_modules/react-router-dom@7.18.1` (direct; `^7.18.1` in frontend/package.json)
94-
95-
**Why remediation is blocked:**
96-
1. **No fix version exists on the registry.** The advisory's stated fix (`8.3.0`) does not exist:
97-
`npm view react-router-dom versions --json` shows the published line tops out at `7.18.1`;
98-
`npm view react-router-dom@latest version``7.18.1`; `npm view react-router-dom@8.3.0 peerDependencies`
99-
`404 Not Found`. There is no 8.x release at all yet. Dependabot alert #86 is citing a not-yet-shipped fix version.
100-
2. **Downgrading within 7.x makes things strictly worse.** `npm audit fix --force` on the installed 7.18.1
101-
suggests downgrading to `react-router-dom@7.11.0`. Verified live: 7.11.0 falls into a *different, much wider*
102-
advisory range (`react-router` `6.0.0 - 7.17.0`) bundling 14 distinct CVEs (open redirect/XSS, SSR XSS in
103-
ScrollRestoration, arbitrary constructor invocation via vendored turbo-stream deserialization → unauth RCE,
104-
DoS via unbounded `__manifest` path expansion, stored XSS via unescaped `Location` header, etc.), versus the
105-
single CSRF-bypass advisory covering `7.12.0 - 8.2.0` that 7.18.1 sits in. No published 7.x or 8.x version is
106-
outside every vulnerable range simultaneously — 7.18.1 (latest available) is the least-exposed option on the
107-
registry today.
108-
3. **App does not use the vulnerable surface.** The CVE requires RSC (React Server Components) mode
109-
(`unstable_RSC`, `RSCStaticRouter`, `ServerRouter`, `react-router/rsc` imports). `grep -rn` across
110-
`frontend/src` found zero matches for any RSC-mode API. Usage is confined to the classic component API:
111-
`BrowserRouter`/`Routes`/`Route`/`useNavigate`/`useParams`/`useSearchParams`/`Link`/`MemoryRouter`
112-
(see `frontend/src/App.tsx:2` and route/test files under `frontend/src/pages/__tests__/`). The CSRF-bypass
113-
action-execution path this advisory describes is not reachable from this codebase's router configuration.
114-
115-
**Exposure & Risk Acceptance:**
116-
- Advisory requires RSC mode; this frontend runs classic SPA routing only (Vite + BrowserRouter), no server
117-
actions, no RSC. Exploitability in this deployment is effectively nil.
118-
- Remediation path is registry-blocked, not effort-blocked — there is nothing to upgrade to yet.
119-
- Acceptance: risk is non-applicable given routing mode in use; no in-range fix exists upstream.
120-
121-
**Recommended follow-ups (revisitBy: 2026-09-01):**
122-
1. Re-check `npm view react-router-dom versions --json` periodically for the `8.3.0` (or later) release landing.
123-
2. When `>=8.3.0` publishes, re-verify its peer `react` requirement (unpublished builds referenced `react>=19.2.7`,
124-
vs. this app's `react: ^18.3.1`) — a React 19 upgrade may be a co-requirement, not just a router bump.
125-
3. Re-run `npm audit --prefix frontend` after any bump attempt to confirm the advisory clears without
126-
reintroducing the wider pre-7.18.1 CVE set.
89+
## GHSA-qwww-vcr4-c8h2 — react-router (RESOLVED 2026-08-11, no longer fires; vestigial root entry pending cleanup)
90+
91+
**Prior claim (now false):** this entry previously asserted no fix version was published for the
92+
7.x line and that `react-router-dom@latest` topped out at `7.18.1`.
93+
94+
**Resolution:** `react-router`/`react-router-dom` **7.18.2** landed via merged PR #67 and is the
95+
advisory's documented `first_patched_version` for the `>=7.12.0, <7.18.2` vulnerable range
96+
(GHSA record vulnerable ranges: `>=7.12.0 <7.18.2` and `>=8.0.0 <8.3.0`; first patched `7.18.2`
97+
and `8.3.0` respectively). `frontend/package.json` declares `"react-router-dom": "^7.18.2"`, and
98+
`frontend/package-lock.json` already resolved `react-router-dom@7.18.2` / `react-router@7.18.2`
99+
`node_modules` was simply stale relative to the lockfile (`npm ls` reported
100+
`invalid: "^7.18.2"` against an installed `7.18.1`) until `npm install` resynced it on
101+
2026-08-11. `npm audit --audit-level=low --prefix frontend` no longer reports this advisory (0
102+
vulnerabilities from react-router).
103+
104+
**Allowlist status (accurate as of this edit):** `GHSA-qwww-vcr4-c8h2` was **never added** to the
105+
new `frontend/.audit-ci.json` (that file was created with an empty allowlist and stays that way —
106+
frontend's own `npm audit` reports 0 vulnerabilities, so nothing there needs allowlisting). The ID
107+
**remains present** in the **root** `.audit-ci.json` allowlist and its `_comment` still says "no
108+
fix version published yet" — that is now stale but is **out of scope** for this change (root
109+
`.audit-ci.json` is intentionally left byte-identical to keep this change's diff scoped to the
110+
frontend gate). Removing the vestigial root entry and correcting its `_comment` is a follow-up,
111+
root-scoped cleanup; the root gate continues to exit 0 either way since audit-ci does not fail on
112+
an allowlisted-but-non-firing advisory (it only warns "Consider not allowlisting advisory:
113+
GHSA-qwww-vcr4-c8h2").

frontend/.audit-ci.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/IBM/audit-ci/main/docs/schema.json",
3+
"low": true,
4+
"moderate": true,
5+
"high": true,
6+
"critical": true,
7+
"allowlist": [],
8+
"report": true,
9+
"skip-dev": false,
10+
"_comment": "Frontend-scoped audit-ci gate (finding 9c287884). Mirrors root .audit-ci.json's severity threshold (low and above, blocking). Empty allowlist: npm audit --prefix frontend currently reports 0 vulnerabilities. If a future advisory is unfixable, add its exact GHSA id here AND a corresponding justification entry in ../audit-ci-allowlist-justifications.md naming that GHSA id."
11+
}

frontend/package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)