Install
$ agentstack add skill-dolphinllc-claude-security-skills-nextjs-attack-probe Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.
Security review
⚠ Flagged1 finding(s); flagged for manual review. · v0.1.0 How review works →
- • Prompt-injection patterns
- • Secret / credential exfiltration
- • Dangerous shell & filesystem operations
- • Untrusted network calls
- • Known-malicious package signatures
- high Reads credentials/environment and may exfiltrate them.
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.
About
Next.js Attack Probe
Authorized probe of a Next.js 13+ App Router app the user owns. Follow [shared probing conventions](../../../PROBING.md) — discover base URL from package.json scripts.dev (default next dev port 3000), next.config.{js,ts} serverRuntimeConfig, Dockerfile EXPOSE, or env (PORT). Never hardcode.
Next.js-specific attack surface
NEXT_PUBLIC_*env vars are baked into the client JS bundle. Any secret with that prefix is leaked to anyone who fetches the site.- Server Actions are reachable via crafted POSTs to any page, with
Next-Action:header — no inherent auth. /_next/data//...json(Pages Router) and route handlers are often forgotten in middleware matchers.next/imageproxy can be coerced into SSRF ifimages.remotePatternsis too permissive.- ISR
revalidatePath/revalidateTagwith user-influenced paths → cache poisoning. x-middleware-subrequestheader bypass (CVE-2025-29927 class) — Next.js /dashboard.json` | 2xx returns protected data = matcher excludes a variant |
| NEXT-SA-001 | high | Capture a Next-Action: header from a logged-in user; replay the POST without cookies | 2xx + state change = server action runs without auth | | NEXT-SA-002 | high | Replay an admin server action with a non-admin user's session | 2xx state change = missing role check inside the action | | NEXT-IMG-001 | high | GET /_next/image?url=http://127.0.0.1:1&w=128&q=75 and ?url=http://169.254.169.254/latest/meta-data/ | Connection succeeds / metadata returned = images.remotePatterns too permissive | | NEXT-IMG-002 | medium | GET /_next/image?url=https://evil.test/x.svg&w=128&q=75 with attacker host | 200 fetched arbitrary remote = host allowlist missing | | NEXT-CACHE-001 | medium | If revalidate webhook exists (POST /api/revalidate?path=...), send path=/admin | 200 + admin page now serves stale/poisoned content | | NEXT-RH-001 | high | OPTIONS /api/* with Origin: https://evil.test + credentials | ACAO reflects + ACAC: true | | NEXT-RH-002 | high | For each /api/* mutating route handler, unauthenticated POST | 2xx = no auth in handler | | NEXT-DBG-001 | low | GET /__nextjs_original-stack-frame?..., /_next/static/development/_devPagesManifest.json | 200 = dev mode reachable in this environment | | NEXT-VER-001 | low | Inspect __next_data__ script tag for buildId; check headers for x-powered-by: Next.js; if version detectable, cross-ref recent CVEs | Version matches a known affected range |
Special handling
- NEXT-ENV-001 is the most common high-impact finding. When confirmed, list each leaked variable name (not value, unless explicitly requested) and the file path inside the bundle.
- NEXT-MW-001 must be reported even if the patch is applied — the user may run multiple Next versions in monorepo.
Wrong vs. right
NEXT-ENV-001 (env leak)
// ❌ This ships to every browser
// .env
NEXT_PUBLIC_OPENAI_API_KEY=sk-live-...
// any component
const key = process.env.NEXT_PUBLIC_OPENAI_API_KEY;
// ✅ Server-only env, called from a route handler
// .env
OPENAI_API_KEY=sk-live-...
// app/api/chat/route.ts
export async function POST(req: Request) {
const key = process.env.OPENAI_API_KEY; // never sent to client
// ...
}
NEXT-SA-001 (unauth server action)
// ❌
"use server";
export async function deleteAccount(id: string) {
await db.user.delete({ where: { id } });
}
// ✅
"use server";
import { auth } from "@/auth";
import { z } from "zod";
const Schema = z.object({ id: z.string().uuid() });
export async function deleteAccount(input: unknown) {
const session = await auth();
if (!session?.user) throw new Error("Unauthorized");
const { id } = Schema.parse(input);
if (session.user.id !== id && session.user.role !== "admin") {
throw new Error("Forbidden");
}
await db.user.delete({ where: { id } });
}
References
- Next.js Server Actions: https://nextjs.org/docs/app/api-reference/functions/server-actions
- Next.js Middleware: https://nextjs.org/docs/app/building-your-application/routing/middleware
- CVE-2025-29927: https://github.com/vercel/next.js/security/advisories/GHSA-f82v-jwr5-mffw
- Next.js Image Optimization: https://nextjs.org/docs/app/api-reference/components/image#remotepatterns
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Dolphinllc
- Source: Dolphinllc/claude-security-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.