plugins/backend-toolkit/skills/backend-security-audit/SKILL.md
Audit a backend against the OWASP API Security Top 10 — BOLA/BFLA, injection, secrets, mass assignment — with an exploit scenario per finding. Use when adding auth/external input, before shipping, or on a quarterly security review. Not for implementing auth from scratch (use authentication / authorization) — each finding maps to its sibling skill for the fix.
npx skillsauth add jaykim88/claude-ai-engineering backend-security-auditInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Systematically check a backend against the OWASP API Security Top 10, producing findings with a concrete exploit scenario each — so the team understands the attack, not just the rule.
Universal — the OWASP API Top 10 is a vendor-neutral, exploit-oriented taxonomy that maps to any backend; only the fix syntax differs.
Audit against the OWASP API Security Top 10 (2023). For each finding, write the exploit scenario (how an attacker abuses it) — this is the differentiator from a generic checklist.
API1 BOLA (Broken Object Level Authorization) — #1, ~40% of API attacks
authorization RLS)API2 Broken Authentication
authentication)API3 Broken Object Property Level Authorization (mass assignment / excessive data exposure)
API5 BFLA (Broken Function Level Authorization)
API4 Unrestricted Resource Consumption
API8 Security Misconfiguration
Injection (cross-cutting)
data-validation)Secrets management (cross-cutting)
gitleaks/trufflehogAPI7 SSRF (Server-Side Request Forgery) — call this out explicitly
fetch / axios → attacker pivots through the server. Defenses: allowlist hosts; block cloud metadata IPs (169.254.169.254 AWS/GCP/Azure, 100.100.100.200 Alibaba, link-local + private CIDRs); validate the resolved IP, not just the input string (DNS rebinding); set a strict timeoutAPI10 Unsafe Consumption of APIs — trust the wire as much as the user
data-validation), cap response sizes, time out generously but not infinitelySameSite=Lax|Strict cookies + origin check on state-changing requests (header-token tokens like Authorization are immune)eslint-plugin-security / semgrep --config=auto + gitleaks + dependency audit; triage each hit; re-run until clean or documented| ❌ Anti-pattern | ✅ Correct |
|---|---|
| Object access by ID with no ownership check | Row-level authz (RLS) verified per request |
| String-concatenated SQL | Parameterized queries / ORM |
| Accepting all body fields (mass assignment) | Explicit DTO allow-list |
| Secrets in env vars shipped to client | Secret manager; server-only; scanned |
| Wildcard CORS on credentialed endpoints | Explicit origin allow-list |
| User-supplied URL fed into fetch (SSRF) | Allowlist hosts; block metadata IPs (169.254.169.254); validate resolved IP, not just input |
| Trusting third-party API response shape (API10) | Validate shape + cap response size + bounded timeout |
| Cookie-auth state-changing endpoint with no CSRF defense | SameSite=Lax/Strict + origin / CSRF-token check |
| Tier | Examples | Action SLA | |---|---|---| | Critical | BOLA leaking other users' data; SQL injection; secret in repo; admin endpoint reachable by regular user (BFLA); SSRF reachable to cloud metadata; cookie-auth state-change with no CSRF defense | Block release; fix immediately | | Major | Missing rate limits; mass assignment; CORS wildcard; trusting third-party API response without validation/size cap | Fix this sprint | | Minor | Verbose error messages; missing security header; outbound URL allow-list maintained ad-hoc | Schedule within 2 sprints |
docs/security-audit-YYYY-MM-DD.md — per finding: OWASP category, file:line, exploit scenario, fix, severityfix(security): <description> [OWASP-API#N, severity]$queryRawUnsafe with interpolationauthorizationclass-validator/Zod (see data-validation)eslint-plugin-security, semgrep --config=auto, gitleaks, npm auditbandit static analysis; Pydantic prevents mass assignment; parameterized SQLAlchemygosec; database/sql parameterized queriessemgrep, gitleaks, trivy work across stacksauthorization — BOLA/BFLA findings are fixed via RBAC + RLSauthentication — broken auth is a top OWASP categorydata-validation — input validation is the first injection defensedevelopment
Design webhooks correctly on both sides — sending (HMAC signing, retries with backoff, at-least-once) and receiving (verify signature on raw body, enqueue + 200 fast, dedupe on event id). Use when adding webhook delivery or consuming a provider's webhooks. Not for internal service-to-service events (use async-messaging) or general outbound-call retry policy (use resilience-patterns).
testing
Use transactions and isolation levels correctly — keep them short, no network calls inside, explicit isolation, retry on serialization conflicts, and choose optimistic vs pessimistic locking. Use when a write spans multiple tables, when concurrent updates corrupt data, or when designing money/inventory flows. Not for cross-service event delivery (use async-messaging Outbox) or schema-level constraints (use schema-design).
development
Backend testing pyramid — unit for pure logic, integration against a real DB (Testcontainers), and consumer-driven contract testing (Pact) for service boundaries. Use before a feature, after a bug fix, or when services break each other on deploy. Not for load testing (use performance-profiling) or security testing (use backend-security-audit).
data-ai
Design a relational schema — normalize to 3NF then denormalize with justification, choose the right Postgres index type per data shape, enforce constraints at the DB. Use when modeling a new domain, when queries are slow, or before a migration. Not for diagnosing slow queries (use query-optimization) or shipping the change without downtime (use migration-strategy).