Skip to content
Skill Authoring
Skill

/api-audit

Use this skill when the user says 'audit API', 'check API security', 'API routes security', 'endpoint audit', 'check my routes', or needs to verify API route protection. Reviews API endpoints for authentication, authorization, and input validation gaps. Do NOT use for frontend

BOOST
From plugin
memstack
42587 skills2 commands4 hooks
Install
$ npx -y skills add cwinvestments/memstack --skill api-audit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/api-audit

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use this skill when the user says 'audit API', 'check API security', 'API routes security', 'endpoint audit', 'check my routes', or needs to verify API route protection. Reviews API endpoints for authentication, authorization, and input validation gaps. Do NOT use for frontend

SKILL.md

api-audit.SKILL.md
name: memstack-security-api-audit
description: "Use this skill when the user says 'audit API', 'check API security', 'API routes security', 'endpoint audit', 'check my routes', or needs to verify API route protection. Reviews API endpoints for authentication, authorization, and input validation gaps. Do NOT use for frontend security headers or dependency scanning."
version: 1.0.0
license: "Proprietary, MemStack™ Pro by CW Affiliate Investments LLC. See LICENSE.txt"

🛡️ API Audit: Checking API Route Security...

*Audit Next.js API routes for authentication, authorization, validation, and common vulnerabilities.*

Activation

When this skill activates, output:

`🛡️ API Audit: Checking API Route Security...`

Then execute the protocol below.

Context Guard

| Context | Status | |---------|--------| | **User asks to audit/check API routes** | ACTIVE: full audit | | **User mentions API security** | ACTIVE: full audit | | **User asks about endpoint protection** | ACTIVE: full audit | | **User is writing a new API route** | DORMANT: let them finish first | | **Non-Next.js project** | DORMANT, not applicable (adapt if Express/Fastify detected) |

Protocol

Step 1: Discover API Routes

Find all API route files in the project:

1. **App Router (Next.js 13+):**

   find . -path "*/app/api/*/route.ts" -o -path "*/app/api/*/route.js"

Each file exports named functions: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`.

2. **Pages Router (legacy):**

   find . -path "*/pages/api/*.ts" -o -path "*/pages/api/*.js"

Each file exports a default handler.

3. **Middleware:**

   find . -name "middleware.ts" -o -name "middleware.js" | head -5

Check if global auth middleware exists (reduces per-route auth requirements).

4. **Server Actions (Next.js 14+):**

   grep -r "'use server'" --include="*.ts" --include="*.tsx" -l

Server actions are also attack surface: treat as API routes. For each server action function, verify it performs authentication before accessing data. Server actions are callable from any client component and receive no automatic auth: they are functionally identical to unauthenticated POST endpoints unless the function explicitly calls `getSession()`, `getAuthContext()`, or equivalent.

Compile a list of all routes with their HTTP methods and file paths.

Step 2: Check Authentication (Check 1)

For each route, determine if it verifies the caller is authenticated:

**Search for auth patterns in each route file:**

  • `getAuthContext` / `getSession` / `getServerSession` / `auth()`: framework auth
  • `getToken` / `verifyToken` / `jwt.verify`: manual JWT
  • `cookies().get` with session validation: cookie-based auth
  • `headers().get('authorization')` with validation: bearer token
  • `createRouteHandlerClient` / `createServerComponentClient`: Supabase auth

**Classify each route:** | Status | Meaning | |--------|---------| | ✅ Authenticated | Auth check found before data access | | 🔴 No Auth | No authentication pattern detected | | ℹ️ Public | Route is intentionally public (webhooks, health checks, public data) | | ⚠️ Middleware-only | Auth handled by middleware, verify matcher covers this route |

**Flag as CRITICAL** if a route performs database writes or returns user-specific data with no auth.

**Known public route patterns** (classify as ℹ️ INFO, not CRITICAL):

  • `/api/health`, `/api/status`: health checks
  • `/api/webhooks/*`: external webhooks (need signature verification instead)
  • `/api/auth/*`: auth flow endpoints (login, callback, register)
  • `/api/public/*`: explicitly named public routes
  • `/api/cron/*`: cron jobs (need secret verification instead)

Step 3: Check Authorization (Check 2)

For authenticated routes, verify they check *what* the user can access:

**Search for authorization patterns:**

  • `verifyOrgAccess` / `checkOrgMembership` / `requireRole`: org-level authz
  • Comparing `user.id` against resource `user_id` / `owner_id`: ownership check
  • Role checks: `user.role === 'admin'` or similar
  • Supabase RLS (may handle authz at database layer: note as INFO)

**Flag as WARNING if:**

  • Route fetches data by ID from params without ownership verification
  • Route accepts `organization_id` from request body instead of deriving from session
  • Multi-tenant route returns data without org scope filter
  • DELETE route has no ownership check

**Pattern to enforce:**

// BAD, trusts client-provided org ID
const { orgId } = await req.json();
const data = await db.from('documents').select().eq('org_id', orgId);

// GOOD, derives org from authenticated session
const { orgId } = await getAuthContext(req);
const data = await db.from('documents').select().eq('org_id', orgId);

Step 4: Check Input Validation (Check 3)

For routes that accept request body or query params:

**Search for validation patterns:**

  • `z.object` / `z.string()` / `.parse(` / `.safeParse(`: Zod
  • `Joi.object` / `.validate(`: Joi
  • `yup.object` / `.validate(`: Yup
  • `body.` or `req.json()` followed by manual type checks: weak validation

**Flag as WARNING if:**

  • Route reads `req.json()` or `request.body` without schema validation
  • Route uses query params in database queries without validation
  • Route passes user input directly to external APIs

**Flag as CRITICAL if:**

  • Route uses dynamic code execution with user input (see Check 5)
  • Route constructs file paths from user input without sanitization

Step 5: Check Rate Limiting (Check 4)

For public-facing routes:

**Search for rate limiting patterns:**

  • `rateLimit` / `rateLimiter` / `limiter` imports
  • `@upstash/ratelimit`: serverless rate limiting
  • `X-RateLimit` header setting
  • Middleware-level rate limiting (check `middleware.ts`)

**Flag as WARNING if:**

  • Login/register routes have no rate limiting (brute force risk)
  • Public data endpoints have no rate limiting (scraping/abuse risk)
  • Webhook endpoints have no rate limiting (replay attack risk)

#

Read more
Ships withmemstack

The structured skill framework for Claude Code: 131 professional skills for deployment, security, databases, content, marketing, and more. Skills activate automatically when you need them. Say "deploy this to Railway" and the right skill loads on demand.

Get the whole plugin

Other skills on memstack.