agentsclimarketplace

Nextjs security

Skill hlsitechio/claude-skills-security/appsec-stack-pack/nextjs-security

Defensive security audit skills for Claude — tech-stack-keyed and audit-domain-keyed packs for SaaS apps.

Install
npx -y skills add hlsitechio/claude-skills-security --skill nextjs-security

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

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, Server Actions, RSC, server components, middleware.ts, route handlers, NEXT_PUBLIC_, Vercel deployment patterns, next.config.js, or asks "audit my Next.js app", "is my middleware safe", "Server Actions security", "Next.js auth review". Trigger when the codebase contains a `next.config.js`/`next.config.mjs`/`next.config.ts` file, `app/` directory with `page.tsx` files, or `pages/` directory with Next.js conventions.

SKILL.md

10.4 KB, as published. Nobody here has run it

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:
    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:
    // 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.
    '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

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.