chore(deps): resolve all open Dependabot security advisories, repair eslint, restrict Pages deploys - #31
Merged
Conversation
craigthackerx
force-pushed
the
chore/security-dependency-updates
branch
from
August 6, 2026 17:45
40ddd6d to
9539618
Compare
Consolidates the five open Dependabot PRs (#23, #27, #28, #29, #30) and fixes the one advisory none of them resolve. Merging all five would clear 22 of the 23 alerts. The straggler is the PostCSS path traversal (#26), and the cause is the overrides block: next 16.3.0 pins postcss 8.5.23, but "postcss": ">=8.5.10" in overrides takes precedence over a transitive pin, and the already-locked 8.5.15 satisfies it. So the override quietly held postcss at a vulnerable version and masked next's own fix. PR #28's lockfile shows this: sharp moves to 0.35.3, postcss stays at 8.5.15. Override floors are raised to the patched versions rather than removed, preserving their intent while preventing drift back onto a vulnerable release: postcss >=8.5.10 -> >=8.5.18 (resolves 8.5.26) dompurify >=3.4.11 -> >=3.4.12 (resolves 3.4.13) next 16.3.0 is taken from #28 rather than the 16.2.12 from group PR #27, since 16.2.12 keeps sharp at ^0.34.5 and would leave advisory #7 open. The other seven bumps from #27 are folded in. Advisories cleared (npm audit: 0 vulnerabilities): next 16.2.7 -> 16.3.0 (#8-#23: SSRF, cache confusion, DoS, middleware bypass) postcss 8.5.15 -> 8.5.26 (#26: path traversal) sharp 0.34.5 -> 0.35.3 (#7: inherited libvips CVEs) dompurify 3.4.11 -> 3.4.13 (#6: CUSTOM_ELEMENT_HANDLING bypass) brace-expansion 5.0.6 -> 5.0.9 (#5, #25, #27: DoS) brace-expansion 1.1.15 -> 1.1.18 (#24: DoS, under eslint-config-next) Also bumps the actions group per #23. No workflow uses pull_request_target or workflow_run, so the breaking fork-checkout change in checkout v7 does not apply here. next-env.d.ts is regenerated by 16.3.0. tsconfig.tsbuildinfo is untracked: it matches *.tsbuildinfo in .gitignore but predates that rule. Verified: npm ci, npx tsc --noEmit, and npm run build all pass; the nextra-theme-docs patch-package patch still applies.
craigthackerx
force-pushed
the
chore/security-dependency-updates
branch
from
August 6, 2026 17:49
9539618 to
a4c6f9a
Compare
Dependency ReviewThe following issues were found:
|
…eploys
Three pre-existing problems, all unrelated to the advisories in the
previous commit.
eslint was non-functional in three ways
--------------------------------------
npm run lint has been dead since the repo moved to Next 16, which removed
the `next lint` subcommand — it was parsed as a directory argument ("no
such directory: .../lint"). There was also no eslint config anywhere in
the repo, so even a working runner had nothing to load. Replaced the
script with `eslint .` and added eslint.config.mjs on eslint-config-next's
flat config.
Third, eslint is pinned back to 9.39.5 from 10.8.0. eslint-config-next
depends on eslint-plugin-react ^7.37.0, and every published version of
that plugin caps its eslint peer at ^9. Under eslint 10 it throws
"contextOrFilename.getFilename is not a function" at rule-load time and
linting cannot run at all. The 10.x pin was never usable; it went
unnoticed only because `next lint` was already broken. dependabot.yml now
ignores eslint majors so this does not silently regress.
All 17 findings fixed
---------------------
react-hooks/set-state-in-effect (6) — every case was the same shape: read
a browser API that does not exist during SSR, then setState in an effect.
Replaced with useSyncExternalStore via two shared hooks in lib/hooks.ts
(useMounted, usePrefersReducedMotion) and a localStorage-backed store in
lib/banner.ts for the docs banner. These read during render instead of
scheduling an extra post-paint update.
react-hooks/rules-of-hooks (2) — false positives. nextra's
useMDXComponents is a factory, not a hook, but the use* name trips the
rule inside async server components. Aliased on import to getMDXComponents.
no-html-link-for-pages (3) — internal <a> to next/link.
no-img-element (3) — <img> to next/image; the devicon CDN host is now
allowlisted in next.config.mjs remotePatterns.
no-anonymous-default-export (3) — _meta.ts objects bound to a name first.
Pages deploy could publish any branch
-------------------------------------
The upload-artifact step and deploy job were gated on
github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch'
The workflow_dispatch arm was not branch-restricted, so dispatching the
workflow from any branch published that branch to the live Pages site.
Dropping that arm closes it while keeping manual redeploys: dispatch on
main still satisfies the ref check; dispatch elsewhere builds without
publishing.
Verified by diffing rendered HTML against origin/main, both clean builds.
Same 42 pages, and the only content change is the <title> ordering on the
built-in 404 (a Next 16.3.0 change; the repo has no custom not-found).
The homepage, which carries every refactored component, is byte-identical
in visible text. Note the nextra "Last updated" dates are nondeterministic
in this project — 16 pages differ between two clean builds of the same
commit — so they are excluded from that comparison.
craigthackerx
force-pushed
the
chore/security-dependency-updates
branch
from
August 6, 2026 18:18
12c6ae9 to
e4ec551
Compare
This was referenced Aug 6, 2026
craigthackerx
had a problem deploying
to
github-pages
August 6, 2026 19:54 — with
GitHub Actions
Failure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consolidates the five open Dependabot PRs (#23, #27, #28, #29, #30), fixes the one advisory none of them resolve, and repairs three pre-existing problems found along the way.
Why one PR
Merging all five Dependabot PRs would clear 22 of the 23 alerts. The one it would leave open is the PostCSS path traversal (#26), and the reason is worth spelling out.
next16.3.0 pinspostcss8.5.23 exactly, which is patched. But theoverridesblock had"postcss": ">=8.5.10", and an override takes precedence over a transitive dependency's own pin. Since the already-locked 8.5.15 satisfies>=8.5.10, npm had no reason to move it — so the override quietly held postcss at a vulnerable version and masked next's fix. PR #28's lockfile shows it:sharpadvances to 0.35.3,postcssstays at 8.5.15.The fix is to raise the floors rather than remove them —
postcssto>=8.5.18(resolves 8.5.26) anddompurifyto>=3.4.12(resolves 3.4.13) — preserving their intent while preventing drift back onto a vulnerable release.This also takes
next16.3.0 from #28 rather than 16.2.12 from #27, since 16.2.12 keepssharpat^0.34.5and would leave advisory #7 open.Advisories cleared
All 23 open alerts, across 5 packages.
npm auditreports 0 vulnerabilities.sourceMappingURLCUSTOM_ELEMENT_HANDLINGbypassPages deploy could publish any branch
The upload-artifact step and deploy job in
nextjs.ymlwere gated on:The
workflow_dispatcharm was not branch-restricted, so dispatching the workflow from any branch published that branch to the live Pages site. Dropping that arm closes it without losing manual redeploys: dispatch onmainstill satisfies the ref check; dispatch elsewhere builds without publishing.eslint was non-functional, in three ways
npm run linthas been dead since the repo moved to Next 16, which removed thenext lintsubcommand — it was parsed as a directory argument (no such directory: .../lint).eslintwas pinned to 10.x, which cannot work here at all.eslint-config-nextdepends oneslint-plugin-react ^7.37.0, and every published version of that plugin caps its eslint peer at^9(7.37.5 is latest; the only prerelease is an ancient 7.8.0-rc.0). Under eslint 10 it throwscontextOrFilename.getFilename is not a functionat rule-load time.Fixed by switching the script to
eslint ., addingeslint.config.mjs, and pinning eslint to 9.39.5.dependabot.ymlnow ignores eslint majors so this cannot silently regress — drop that entry once the plugin supports eslint 10.All 17 findings fixed
react-hooks/set-state-in-effectuseSyncExternalStorevia shareduseMounted/usePrefersReducedMotionhooks and a localStorage-backed store for the docs banner. Reads during render instead of scheduling an extra post-paint update.react-hooks/rules-of-hooksuseMDXComponentsis a factory, not a hook, but theuse*name trips the rule inside async server components. Aliased on import togetMDXComponents.@next/next/no-html-link-for-pages<a>tonext/link.@next/next/no-img-element<img>tonext/image; the devicon CDN host allowlisted inremotePatterns.import/no-anonymous-default-export_meta.tsobjects bound to a name before export.Verification
npm ci,npm run lint,npx tsc --noEmitandnpm run buildall pass clean,npm auditreports 0 vulnerabilities.Because this refactors six components, I diffed the rendered HTML against
origin/mainwith both sides built clean. Same 42 pages, and the only content change is<title>ordering on the built-in 404 — a Next 16.3.0 change; the repo has no custom not-found page. The homepage, which carries every refactored component, is identical in visible text.One thing worth knowing independently of this PR: the nextra "Last updated" dates are nondeterministic. Two clean builds of the same commit produce different dates on 16 of 42 pages, so they are excluded from the comparison above.
Superseding #23, #27, #28, #29, #30 — these should close automatically once this merges.