AgentStack
SKILL verified MIT Self-run

Nextjs Security

skill-hlsitechio-claude-skills-security-nextjs-security · by hlsitechio

Security audit specific to Next.js applications including App Router and Pages Router, Server Actions, middleware, Route Handlers, Server Components, environment variable exposure (NEXT_PUBLIC_), getServerSideProps/getStaticProps secret leakage, Image Optimization SSRF, and Next.js-specific authentication patterns. Use this skill whenever the user mentions Next.js, App Router, Pages Router, Serve…

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-hlsitechio-claude-skills-security-nextjs-security

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Nextjs Security? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Next.js Security Audit

Audit a Next.js application for framework-specific vulnerabilities. Covers App Router (13+) and Pages Router. Defensive focus.

When this skill applies

  • Reviewing Next.js apps for security issues
  • Auditing Server Actions, Route Handlers, middleware
  • Reviewing environment variable usage (the NEXT_PUBLIC_ trap)
  • Checking authentication patterns specific to Next.js
  • Identifying SSRF in next/image configurations
  • Auditing the differences between Server and Client Components

Use other skills for: generic React patterns (react-security), backend services Next calls (nodejs-express-security etc.), auth providers (clerk-security, nextauth-security), Vercel platform settings (vercel-platform-security).

Workflow

Follow ../_shared/audit-workflow.md. Next.js-specific notes below.

Phase 1: Stack detection

  • Next.js version (13, 14, 15 — App Router behaviors differ)
  • Router model: App Router (app/), Pages Router (pages/), or hybrid
  • Deployment target: Vercel, self-hosted Node, edge runtime, static export
  • Auth: NextAuth/Auth.js, Clerk, custom JWT, Supabase Auth, other

Phase 2: Inventory

# Layout
find . -name 'next.config.*' -not -path '*/node_modules/*'
find app -type f \( -name 'page.tsx' -o -name 'route.ts' -o -name 'layout.tsx' \) 2>/dev/null | head -20
find pages -type f \( -name '*.tsx' -o -name '*.ts' \) 2>/dev/null | head -20

# Server Actions (App Router)
grep -rn "'use server'" app/ src/ 2>/dev/null | head -50

# Middleware
find . -name 'middleware.ts' -o -name 'middleware.tsx' -o -name 'middleware.js' 2>/dev/null | head

# Environment variable references
grep -rn "process.env" app/ src/ pages/ 2>/dev/null | head -50

# next/image config (image optimization)
grep -n 'images:\|remotePatterns\|domains:' next.config.* 2>/dev/null

Phase 3: Detection — the checks

Environment variables — the NEXT_PUBLIC_ trap
  • NXT-ENV-1 Variables prefixed with NEXT_PUBLIC_ are inlined into the client bundle at build time. Anything not strictly public must NOT have this prefix.
  • NXT-ENV-2 Common mistakes: NEXT_PUBLIC_STRIPE_SECRET_KEY, NEXT_PUBLIC_DATABASE_URL, NEXT_PUBLIC_API_KEY — all of these have shipped to production at multiple companies. Audit every NEXT_PUBLIC_ for "is this really public?"
  • NXT-ENV-3 Verify by building and inspecting:

``bash npm run build && \ grep -rhE 'NEXT_PUBLIC_[A-Z_]+' .next/static/chunks/*.js | sort -u # If any NEXT_PUBLIC_*_SECRET or NEXT_PUBLIC_*_KEY values show up, that's a leak ``

  • NXT-ENV-4 Server-only secrets read from process.env.SOMETHING_SECRET only in server components, server actions, route handlers, or getServerSideProps / getStaticProps. Never reference them in a Client Component or shared utility imported by both.
Server vs Client Components (App Router)
  • NXT-RSC-1 Files with "use client" are Client Components and ship to the browser; nothing in their import graph can contain secrets.
  • NXT-RSC-2 Files without "use client" in app/ are Server Components — they can read secrets but must NOT pass them as props to Client Components (props serialize to the client).
  • NXT-RSC-3 Use the server-only package to fail-fast on accidental client imports of server modules:

``ts // lib/db.ts import 'server-only'; export const db = createDbClient(process.env.DATABASE_URL!); `` If any Client Component transitively imports this, the build fails.

  • NXT-RSC-4 Use client-only similarly for browser-only modules.
Server Actions

Server Actions ("use server") are POST endpoints generated by Next, callable from forms or directly from Client Components. They're a common new XSS-equivalent attack surface.

  • NXT-SA-1 Every Server Action checks authentication. There's no implicit auth — Next doesn't add one.

```ts 'use server'; import { auth } from '@/lib/auth';

export async function deletePost(postId: string) { const session = await auth(); if (!session?.user) throw new Error('Unauthorized'); // ... and check the user owns the post } ```

  • NXT-SA-2 Server Actions check authorization on the specific resource — not just "is user authenticated" but "does user own/have-access-to this object".
  • NXT-SA-3 Input validated with Zod or similar; never trust the shape of the FormData / serialized args.
  • NXT-SA-4 Server Actions don't accept userId / tenantId as args — derive from session.
  • NXT-SA-5 Mutation Server Actions handle CSRF correctly. Next has built-in protection for Server Actions called via form submission with the same-origin policy, but custom invocations need verification.
  • NXT-SA-6 Server Actions that perform sensitive operations have rate limiting (no built-in; use a Redis/Upstash counter).
Route Handlers (App Router) and API Routes (Pages Router)
  • NXT-RH-1 Every Route Handler in app/.../route.ts and every API route in pages/api/ checks auth.
  • NXT-RH-2 No accidental data exposure — handlers return only what the caller is authorized to see.
  • NXT-RH-3 CORS configured per handler when needed; not globally permissive.
  • NXT-RH-4 Webhook receivers (Stripe, Resend, etc.) verify signatures — see saas-security-pack/saas-api-security/references/webhook-security.md.
  • NXT-RH-5 Catch-all routes ([...slug]/route.ts) validate the captured path; common path traversal vector.
Middleware

middleware.ts runs before every matched request — a powerful place to enforce, also a powerful place to introduce bugs.

  • NXT-MW-1 Middleware that performs auth checks: ensure it's actually applied to the routes you think (the config.matcher field).
  • NXT-MW-2 Middleware running on the Edge runtime can't use Node.js APIs; if you need crypto for HMAC, use the Web Crypto API.
  • NXT-MW-3 Middleware doesn't leak: don't put sensitive headers, cookies, or info-disclosure into rewrites/responses from middleware.
  • NXT-MW-4 Middleware should not be the only auth check — it's easy to misconfigure matcher and route around. Server Actions / Route Handlers still check.
  • NXT-MW-5 request.headers.get('x-forwarded-for') and similar are spoofable client-side except behind a properly-configured reverse proxy. Don't use for security decisions without verifying the proxy chain.
Image Optimization SSRF

next/image can fetch from any URL listed in images.remotePatterns / images.domains in next.config.js and proxy through your server. Bad configs become SSRF.

  • NXT-IMG-1 images.remotePatterns lists specific hostnames; no wildcards like **.
  • NXT-IMG-2 No legacy images.domains: ['*'] config.
  • NXT-IMG-3 Self-hosted Next.js: image optimizer can fetch internal IPs unless restricted. The Vercel-hosted version blocks RFC1918; self-hosted defaults more permissive.
  • NXT-IMG-4 If users can supply image URLs (avatars, embeds), the URLs go through next/image which proxies through your server — making your server the source IP for the fetch. Validate URLs before passing to next/image.
// BAD
module.exports = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: '**' }],  // any host
  },
};

// GOOD
module.exports = {
  images: {
    remotePatterns: [
      { protocol: 'https', hostname: 'images.yourcdn.com' },
      { protocol: 'https', hostname: '*.s3.amazonaws.com', pathname: '/yourbucket/**' },
    ],
  },
};
Session and auth handling
  • NXT-AUTH-1 Session cookies follow the patterns in saas-security-pack/saas-frontend-hardening/references/cookie-config.md.
  • NXT-AUTH-2 If using NextAuth: see nextauth-security skill.
  • NXT-AUTH-3 If using Clerk: see clerk-security skill.
  • NXT-AUTH-4 Custom JWT: validate signature on every request; rotate JWT secret periodically; see saas-security-pack/saas-code-security-review/references/jwt-validation.md.
  • NXT-AUTH-5 Login redirect URLs validated against allowlist (open redirect via callbackUrl=...).
Static export vs runtime
  • NXT-EXP-1 Static-exported pages don't run server logic at request time; auth checks intended to run server-side don't. Confirm the deployment mode matches the security model.
next.config.js security flags
  • NXT-CFG-1 headers() configured to add CSP, HSTS, X-Content-Type-Options, etc. (see saas-security-pack/saas-frontend-hardening).
  • NXT-CFG-2 poweredByHeader: false (removes X-Powered-By: Next.js — info disclosure).
  • NXT-CFG-3 reactStrictMode: true — not strictly security, but surfaces hydration mismatches that can have security implications.
  • NXT-CFG-4 Custom redirect / rewrite rules don't accept user-controllable targets without validation (open redirect).
Dependency hygiene
  • NXT-DEP-1 Next.js version is a recently-patched release. Several Next.js versions have had Critical CVEs:
  • CVE-2024-46982 (cache poisoning on Pages Router)
  • CVE-2024-34351 (SSRF via Server Actions)
  • CVE-2025-29927 (middleware bypass — fixed in 14.2.25 / 15.2.3)
  • older CVEs in 13.x

Pin to the latest patch of your supported major; review release notes for security fixes.

Phase 4: Triage

Critical class examples:

  • NEXT_PUBLIC_*_SECRET env vars (definitive client leak)
  • Server Action without auth check performing sensitive ops
  • Middleware-only auth bypassable via specific URL pattern (see CVE-2025-29927 class)
  • next/image with wildcard remote patterns
  • Server Component passing secret-bearing prop to Client Component

Phase 5: Report

Use ../_shared/findings-schema.md. Prefix IDs with NXT-.

References

  • references/app-router-patterns.md — Server Actions, RSC, middleware patterns and pitfalls

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.