APIs are the most exposed part of your application: public by design, documented for convenience, and frequently the last thing that gets security tested. This checklist turns the OWASP API Security Top 10 into concrete checks you can run before every release.
Copy it into your PR template or your pre-launch doc. Each item maps to an OWASP API risk so you know why it matters.
1. Authentication
- Every non-public endpoint rejects requests with no token (401).
- Expired and tampered tokens are rejected; JWT signature and expiry are validated server-side.
- Tokens are short-lived and refresh tokens can be revoked.
- No endpoint accepts credentials in the URL or query string.
OWASP API2: Broken Authentication.
2. Authorization (the big one)
- Object-level: every request that takes an ID checks that the current user owns the resource. Changing the ID to another user's must return 403/404, not their data.
- Function-level: admin-only routes reject normal-user tokens.
- Property-level: users can't set protected fields (
role,isAdmin,price) via mass assignment.
OWASP API1 (BOLA), API3 (Property-level), API5 (Function-level) — the most exploited risks.
// The BOLA check every endpoint needs
const order = await db.order.findFirst({
where: { id: params.id, userId: session.user.id }, // scope to owner
})
if (!order) return new Response(null, { status: 404 })3. Rate limiting & resource consumption
- Login, signup, password reset and payment endpoints are throttled.
- Pagination is capped (no
?limit=1000000). - Request body size is limited; expensive queries have timeouts.
OWASP API4: Unrestricted Resource Consumption.
4. Input validation
- All input is validated server-side against a schema (length, type, format).
- Database access uses parameterized queries or an ORM — never string-built SQL.
- Output is escaped; file uploads are type- and size-checked.
5. Secrets & configuration
- No secrets in client code or committed
.envfiles. - Only publishable/anon keys are ever public; service-role and secret keys stay server-side.
- Any leaked key is rotated and treated as compromised.
- If you use Supabase, Row Level Security is on for every table (see the RLS guide).
OWASP API8: Security Misconfiguration.
6. Transport & headers
- HTTPS enforced; HSTS set.
- CORS restricted to known origins — no
Access-Control-Allow-Origin: *on authenticated APIs. - Security headers present: CSP, X-Content-Type-Options, X-Frame-Options.
7. Errors, inventory & monitoring
- Errors return generic messages — no stack traces, SQL or internal paths.
- Old/undocumented endpoints (
/v1/,/internal/) are removed or protected. - You are alerted when error rates spike — a live attack shows up as a flood of 401/403/400 long before it shows up in a report.
OWASP API8, API9 (Improper Inventory Management).
Automate the checklist
A checklist is only as good as how often you run it. Two layers cover most of this automatically:
- Pre-deploy scanning — catch exposed secrets, missing auth and misconfigurations before they ship. Nurbak scans a deployed app for these exact issues and returns a prioritized report.
- Runtime monitoring — attacks don't wait for your test schedule. Nurbak Watch tracks error rates per endpoint and alerts you in seconds when
/api/loginsuddenly returns 500 failed auths in a minute.
// instrumentation.ts
import { initWatch } from '@nurbak/watch'
export function register() {
initWatch({ apiKey: process.env.NURBAK_WATCH_KEY })
}
