Framework-Specific Security Checks
Detect framework from package.json, then apply the matching section.
node -e "const p=require('./package.json'); console.log({...p.dependencies,...p.devDependencies})" 2>/dev/null
React
- No
dangerouslySetInnerHTMLwithout DOMPurify sanitization - User-controlled
hrefin links validated (javascript:blocked) - Keys not derived from user input in security-sensitive lists
- Third-party components audited for XSS
- Environment variables: only
REACT_APP_*/VITE_*in client (never secrets)
rg -n "dangerouslySetInnerHTML|innerHTML" --glob "*.{jsx,tsx}"
Next.js (App Router & Pages)
- Server Actions validate auth + input on every invocation
-
middleware.tscovers all sensitive routes (not bypassable via direct API) -
next.config.jsheaders: CSP, HSTS, X-Frame-Options -
images.domains/remotePatternsallowlist (no open proxy) - Dynamic routes:
paramsvalidated before DB queries -
NEXT_PUBLIC_*vars contain no secrets - Server Components don't leak secrets to client props
-
revalidatePath/revalidateTagnot callable by unauthenticated users
rg -n "'use server'|use server" --glob "*.{js,ts,jsx,tsx}"
rg -n "NEXT_PUBLIC_" --glob ".env*"
ls middleware.ts 2>/dev/null && cat middleware.ts
See nextjs.md for detailed checks.
Express
-
helmet()configured with strict CSP -
express.json({ limit: '...' })body size limit - Rate limiting (
express-rate-limit) on auth routes -
req.params/req.queryvalidated, not passed raw to DB - Static file serving doesn't expose
.env,node_modules -
app.set('trust proxy', ...)configured correctly behind reverse proxy - No
res.send(userInput)without encoding
rg -n "app\.(get|post|put|delete|use)\(" --glob "*.{js,ts}"
rg -n "helmet|rateLimit|csrf" --glob "*.{js,ts}"
See express.md.
Fastify
- JSON schema validation on all routes (
schemaoption) -
@fastify/helmetregistered -
@fastify/rate-limiton sensitive routes -
@fastify/corswith explicit origin allowlist -
trustProxyset correctly
Vue / Nuxt
- No
v-htmlwith unsanitized user content - Nuxt
runtimeConfigsecrets not inruntimeConfig.public - Nuxt server routes (
server/api/) have auth checks -
useFetch/$fetchSSRF: URLs not user-controlled - Vue router guards + server-side auth (not guards alone)
rg -n "v-html" --glob "*.{vue,js,ts}"
rg -n "runtimeConfig" --glob "nuxt.config.*"
Svelte / SvelteKit
-
{@html}only with sanitized content -
+server.tsendpoints validate auth - Form actions validate CSRF (SvelteKit built-in) + auth
-
$env/static/publicvs$env/static/privateused correctly -
hooks.server.tsenforces session on protected routes
Hono
-
validatormiddleware on all routes -
secureHeaders()middleware applied -
corswith explicit origins - Cloudflare Workers: secrets via bindings, not env literals
-
c.envbindings typed via generated types
Node.js (General)
- No sync file/network ops blocking event loop on hot paths
-
fsoperations use resolved paths with prefix validation -
crypto.randomBytesfor tokens (notMath.random) - TLS cert validation not disabled (
rejectUnauthorized: false) -
npmscripts don't execute untrusted postinstall hooks blindly
Detection & Routing
| Detected | Priority checks |
|---|---|
next |
Server Actions, middleware, env vars |
express |
Helmet, auth middleware coverage, input validation |
fastify |
Schema validation, plugins |
react (CRA/Vite) |
XSS, client secrets |
vue / nuxt |
v-html, server routes, runtimeConfig |
@sveltejs/kit |
+server auth, {@html} |
hono |
validator, secureHeaders, bindings |
Finding Format
### [Framework] Finding Title
- **Framework:** Next.js 14 App Router
- **Check:** Server Action auth
- **Location:** `app/actions/checkout.ts`
- **Issue:** `processPayment` callable without session check
- **Fix:** Add `const session = await auth(); if (!session) throw new Error('Unauthorized')`
References
- nextjs.md — App Router, middleware, Server Actions
- express.md — middleware stack, common vulns