From hypervibe
Audit the security of a Next.js/T3 project. Checks for exposed secrets, unprotected routes, input validation, dependency vulnerabilities, headers, CORS, and common web security issues. Use when the user wants to verify their app is safe before going live.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hypervibe:securityThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You audit the security of the project and propose concrete fixes. You explain each problem simply, without scaring the user unnecessarily.
You audit the security of the project and propose concrete fixes. You explain each problem simply, without scaring the user unnecessarily.
Disclaimer to display at the start of the audit:
⚠️ Important: this audit covers common security flaws and frequent mistakes. It does not replace a professional security audit. If your app handles sensitive data (health, banking, critical personal data), have it validated by a security expert.
The report must be readable by someone who is not a developer. The user is often someone who has just put their app online and wants to understand what they are risking, not a security specialist.
Concrete rules:
This rule applies to the report (step 2) and to the fix proposals (step 3). In your internal scan (step 1), you can stay brief and technical.
At startup, display a checklist in natural language. During execution, announce with ↳ … then mark ✅. Never "Step N" internally in your user-facing messages. Never the internal skill names prefixed with _, describe them in plain language.
Analyze the project and check each point. For each point, indicate:
.ts, .tsx, .js files. Look for patterns: sk_live_, re_, whsec_, ghp_, Bearer , password, secret, apiKey followed by a hardcoded value..env and not in the code..env, .env.local, .env.production, node_modules/, .next/.git log --all --diff-filter=A -- .env .env.local .env.production whether a .env file has ever been committed (even if it was deleted afterward, the secrets are in the history).NEXT_PUBLIC_ are accessible client-side. Secrets (API keys, tokens) must NEVER have this prefix.protectedProcedure or manual session verification).httpOnly, secure, sameSite flags.getOrder({ id }), deleteDocument({ id })...), verify that the query also filters by the session user (where userId = session.user.id) or checks ownership before acting. Being logged in is NOT enough: without this check, any logged-in user can read or modify any other user's data just by changing the id. This is one of the most common flaws in apps built quickly - check every procedure that takes an id, one by one.src/app/api/**/route.ts) that changes state must verify the session AND reject requests a simple cross-site form could send (check the Content-Type and/or the Origin header).[id]) are validated and typed before being used in DB queries.sql template literals with unescaped variables).sql```, db.execute, $queryRaw` and verify that user variables are passed via parameters, not by concatenation.Check in next.config.js or the middleware whether the following headers are configured:
Access-Control-Allow-Origin is not * in production (too permissive).Use npm audit with a temporary lockfile rather than pnpm audit (pnpm 10 always hits the old deprecated endpoint /audits/quick → HTTP 410):
npm install --package-lock-only --silent 2>&1
npm audit --omit=dev --json 2>&1
rm -f package-lock.json
--omit=dev).pnpm update <pkg>@<safe-version> for each vulnerable package (read fixAvailable.version in the JSON output).next version explicitly (it appears in the audit output like any package, but treat it as its own finding). Pay special attention to the middleware authorization bypass class of CVEs (e.g. CVE-2025-29927: a spoofed internal header let attackers skip middleware auth checks entirely). If next is affected by a critical advisory, upgrading it is a 🔴, not a ⚠️.console.log statements that could expose sensitive data in production.next.config.js does not disable protections (e.g. poweredBy should be false, reactStrictMode should be true)./api/webhooks/* or any route a third-party service calls) must verify the provider's signature BEFORE processing the payload. Stripe: stripe.webhooks.constructEvent(rawBody, signature, STRIPE_WEBHOOK_SECRET) - flag any handler that parses the body without it. Same principle for Brevo, GitHub, etc. Consequence if missing: anyone who finds the URL can forge a "payment succeeded" event and get the product for free.fetch/HTTP call whose URL comes, even partially, from user input: a form field, a query param, a value stored in DB that users can write (avatar URL, webhook URL, RSS feed...).https only, expected hosts only, and never internal addresses (localhost, 127.0.0.1, 10.x, 192.168.x, 169.254.169.254...). Consequence if not: an attacker can make your server call internal services or the cloud provider's metadata endpoint, and exfiltrate credentials from inside.Present the report:
Security audit - Results
🔴 Critical (X points) - fix immediately:
- (list of critical problems with a simple explanation)
⚠️ To improve (X points):
- (list with explanation)
✅ OK (X points): (condensed list)
Score: X/Y
⚠️ Reminder: this audit covers common flaws. For sensitive data or a critical project, consult a security professional.
Ask the user:
Do you want me to fix the 🔴 critical problems now?
If yes, fix in this order of priority:
.env, check .gitignore. If a .env was committed in the past, remove it from the git history and regenerate all the affected keys (the history remains accessible).protectedProcedure or session check) AND the ownership filters (where userId = session.user.id) on every procedure that accesses a record by id.constructEvent on the raw body, etc.) before any payload processing.node "${CLAUDE_SKILL_DIR}/../../scripts/setup-security.mjs" (idempotent: injects the headers into the EXISTING next.config without regenerating it - wrapped configs like next-intl and custom options survive - + console.log isDev guard + rate-limit.ts + rateLimitedProcedure if not already in place; also removes the deprecated X-XSS-Protection header if present). Two follow-ups after running it:
headers() already present, or config object not found), apply the securityHeaders block manually in next.config by merging it with what exists.rateLimitedProcedure error message in English: if the project's audience is not English-speaking, translate that message in src/server/api/trpc.ts into the site's language.npm audit --omit=dev (generated in 1g) to identify the affected packages, then pnpm update <pkg>@<safe-version> for each. pnpm audit --fix also depends on the old deprecated endpoint, do not rely on it.After the fixes, before reporting: run pnpm tsc --noEmit && pnpm lint and fix any error they raise. Never leave the project in a state that does not compile or lint (never use pnpm build for this check).
After the fixes, quickly re-run the checks on the points that were 🔴 or ⚠️ and display the new score. Confirm that pnpm tsc --noEmit && pnpm lint passed (run in Step 3); if a fix was applied after that check, run it again.
✅ Audit complete. Score: X/Y → X/Y
Reminder: if your app handles sensitive data, have it audited by a professional before going to production.
npx claudepluginhub flavien-ia/hypervibe-harness --plugin hypervibeRuns dependency vulnerability audits, secret scanning, OWASP pattern detection, and HTTP header checks to harden project security.
Scans code for OWASP Top 10 vulnerabilities, exposed secrets, broken auth, injection attacks, and insecure dependencies. Use before shipping or during code review.
Audits source code against OWASP Top 10 (2021) vulnerabilities — broken access control, injection, SSRF, cryptographic failures, and more. Useful when reviewing application security or checking for common weaknesses.