Statically review Nuxt 3/4 full-stack code for private secrets exposed via runtimeConfig.public/NUXT_PUBLIC_* env vars, useState/module-scope cross-request state pollution in Nitro, server-route SSRF via $fetch/ofetch with blind useRequestHeaders/credential forwarding, NuxtPayload/useState serialization reaching an XSS sink, and missing security response headers (routeRules headers, nuxt-security), grounded in Nuxt's own documentation via Context7.
Scanned 9/4/2026
Install to Claude Code
npx -y skills add VincentChuWaiChow/vanguard-frontier-agentic --skill nuxt-fullstack-security-review --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Nuxt Fullstack Security Review?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/vincentchuwaichow-nuxt-fullstack-security-review)More formats (shields.io, HTML) on the badges page.
---
name: nuxt-fullstack-security-review
description: Statically review Nuxt 3/4 full-stack code for private secrets exposed via runtimeConfig.public/NUXT_PUBLIC_* env vars, useState/module-scope cross-request state pollution in Nitro, server-route SSRF via $fetch/ofetch with blind useRequestHeaders/credential forwarding, NuxtPayload/useState serialization reaching an XSS sink, and missing security response headers (routeRules headers, nuxt-security), grounded in Nuxt's own documentation via Context7.
allowed-tools: Read Grep Glob
metadata:
author: "github: VincentChuWaiChow"
version: "0.1.0"
updated: "2026-07-03"
category: security
---
# Nuxt Fullstack Security Review
## Purpose
Review Nuxt 3/4 full-stack code — `nuxt.config.ts`, `composables/`, `plugins/`,
`server/api/`, `server/routes/`, `server/middleware/`, and templates using
`useState`/`v-html` — for five defect classes Nuxt's own documentation and its
long-lived Nitro server model make security-critical: (a) private secrets placed
under `runtimeConfig.public` (or fed by `NUXT_PUBLIC_*` env vars) so they ship in the
client bundle, (b) `useState`/module-scope reactive or mutable state leaking across
requests in Nitro's single long-lived process, (c) server-route SSRF via
`$fetch`/`ofetch` to a user-controlled URL and blind forwarding of
`useRequestHeaders()`/credentials, (d) `NuxtPayload`/`useState` data reaching an
unsanitized render sink (XSS), and (e) missing security response headers
(`routeRules` `headers`, the `nuxt-security` module, `useResponseHeader`). This
skill exists so the review stays anchored to these five documented, structural
defect classes instead of drifting into a general "Nuxt code review."
## When to use
Use this skill when the user asks to:
- review a Nuxt `nuxt.config.ts` `runtimeConfig`/`routeRules` block for
secret-exposure or missing-header risk,
- review a `server/api/*` or `server/routes/*` handler that calls out to another
service (`$fetch`/`ofetch`/`event.$fetch`),
- investigate a report of one user seeing another user's data from a Nuxt app — the
classic cross-request state pollution symptom,
- assess whether a `useState`/payload value rendered with `v-html` is safe,
- perform a pre-launch security review of a Nuxt 3/4 full-stack application.
Do not use this skill for:
- a Nuxt app's client-only component architecture, composable-extraction quality, or
reactivity-boundary design with no security angle — use
`vue-composition-api-architecture-review` instead,
- general Vue SSR concerns (non-Nuxt `entry-server.js`, raw `@vue/server-renderer`
usage) with no Nuxt-specific API involved — use `vue-ssr-security-review` instead,
- Vuex/Pinia store internals or Vue Router navigation-guard security with no
Nuxt-specific `runtimeConfig`/`server/`/`useState` surface — use
`vue-state-store-security-review` or `vue-router-navigation-security-review`
instead,
- a bug that requires live traffic reproduction (concurrent-request load testing, a
captured cross-user response, an actual SSRF probe against a running deployment) to
confirm exploitation — static analysis proves the structural risk, not that it has
already been exploited in production.
## Context7 Documentation Protocol
- Resolve and query `/websites/nuxt_4_x` (primary; Nuxt 4 prose docs) and
`/websites/nuxt_3_x` (Nuxt 3 prose docs) before citing any `runtimeConfig`,
`useState`, `$fetch`/`event.$fetch`/`useRequestFetch`/`useRequestHeaders`,
payload/`devalue`, `routeRules`, or `useResponseHeader` behavior as fact. Both are
Nuxt's own documentation site content mirrored into Context7 — treat matches from
either as `documentation-based`.
- Confirm which Nuxt major the target repo uses (`package.json`'s `nuxt` dependency)
before assuming version-specific defaults; the APIs this skill covers are stable
across 3/4, but state which major was confirmed when citing a claim.
- The third-party `nuxt-security` module's exact default header set and
configuration surface is **not** covered by Nuxt's own Context7-indexed docs —
never state a specific default for it as `documentation-based`. Confirm its
presence/config by reading the repo's `nuxt.config.ts` directly, and label any
claim about its behavior `inference` unless corroborated by the module's own
documentation (not currently in scope for this skill's Context7 grounding).
- Do not invent API names. If Context7 does not confirm an API or default, say so
explicitly and label the claim `inference`.
- If Context7 is unavailable, fall back to the `official_docs` URLs in this skill's
`metadata.json` and label the claim `documentation-based, unverified against
current release`.
## Lean operating rules
- Every finding in this skill's five defect classes defaults to HIGH severity
(missing-security-headers may be MEDIUM-to-HIGH depending on the app's actual
surface — see `references/ssrf-payload-and-response-headers.md`, Part 3). Do not
downgrade a structural `runtimeConfig` exposure, cross-request state leak, SSRF
path, or payload-XSS trace to informational because it has not been observed
exploited yet.
- Trace every finding to a concrete file:line and a concrete data-flow path. A
finding that says "this might leak the secret" or "this fetch call could be
SSRF" without showing the specific config key, the specific module-scope
declaration and its reachability, or the specific origin-to-sink trace is a
guess, not a finding.
- Classify every `runtimeConfig` key by its actual nesting (top-level = private,
under `public` = client-exposed) — never by variable name alone. A key named
`apiSecret` sitting inside `public` is exposed; a key named `baseUrl` sitting
outside `public` is still private and not itself a finding.
- Classify every module-scope declaration on two axes before flagging it:
mutability/reactivity (only `useState`/`ref`/`reactive`/mutable objects are at
risk; immutable constants are not), and reachability from server-rendered code
(a declaration no server-rendered path ever touches is not a finding in this
scope).
- Do not clear a `$fetch`/`ofetch`/`event.$fetch` call in a server route as safe
from SSRF just because it "looks like an API call" — trace the destination URL
to its origin and confirm either a hardcoded host or an explicit allowlist check
before the request fires.
- Do not clear a header-forwarding call (`event.$fetch`'s default forwarding,
`useRequestHeaders(...)`, or manual header spreading) as safe just because
Nuxt documents the mechanism — the mechanism existing is not the same as its
use being scoped to only the headers actually needed and only trusted
destinations.
- Do not approve a `useState`/payload value reaching a `v-html` binding unless a
named sanitizer call is visibly present on that exact traced path — a sanitizer
existing elsewhere in the codebase does not clear this bar.
- Do not report "no security headers" as cleared just because *a* mechanism
exists somewhere in the config — confirm the `routeRules` glob (or module
config) actually covers the routes in scope before crediting it.
- Never execute, build, or run application code, and never send live requests, as
part of this review; this is a static-review skill (Read/Grep/Glob only).
- Load only the reference needed for the concern in scope.
## References
Load these only when needed:
- [Review workflow and findings contract](references/workflow-and-output.md) — use
for the step-by-step review procedure, the full decision tree across all five
defect classes, and the required output shape.
- [runtimeConfig exposure and cross-request state pollution](references/runtime-config-and-cross-request-state.md)
— load when reviewing `nuxt.config.ts`'s `runtimeConfig` block, `NUXT_PUBLIC_*`
env vars, or `useState`/module-scope reactive/mutable declarations reachable
from server-rendered code.
- [Server-route SSRF, header forwarding, payload XSS, and missing response headers](references/ssrf-payload-and-response-headers.md)
— load when reviewing a `server/api`/`server/routes` handler's outbound
`$fetch`/`ofetch`/`event.$fetch`/`useRequestFetch` calls, a `useState`/payload
value that renders somewhere, or `routeRules`/security-module configuration.
- [Acceptance rubric](references/acceptance-rubric.md) — the authoritative list of
defects this skill must catch and the false positives it must not raise; consult
when unsure whether a pattern is in scope.
## Response minimum
Return, at minimum:
- the `runtimeConfig`/`routeRules` blocks, module-scope declarations, server
routes, and/or template bindings in scope,
- ranked findings with file:line evidence, defect category
(`runtimeconfig-exposure` / `cross-request-state-pollution` / `ssrf` /
`credential-forwarding` / `payload-xss` / `missing-security-headers`), the
concrete data-flow trace, and a fix sketch matching Nuxt's documented pattern,
- for every `useState`/payload → render-sink finding, an explicit statement of
whether a sanitizer call is present on the traced path — never approve on the
assumption one exists elsewhere,
- evidence level per finding (`repo evidence`, `documentation-based`, or
`inference`), with structural risk findings explicitly labeled as structural
risk, not as confirmed-exploited,
- verdict (approve / approve-with-notes / block),
- open questions or scope the review could not cover (e.g., "confirming actual
cross-request leakage requires concurrent-request load testing, not static
review").
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!