APIs handle authentication tokens, payment data, and personal information. They're also the most exposed surface of your application — public by design, documented for convenience, and often the last thing that gets security tested.

In 2026, APIs are the #1 attack vector for web applications. This guide covers the OWASP API Security Top 10, practical testing techniques, and tools you can use today.

OWASP API Security Top 10 (2023 Edition)

#VulnerabilityWhat it meansHow to test
1BOLA (Broken Object Level Auth)User A can access User B's data by changing the IDChange resource IDs in requests with a different user's token
2Broken AuthenticationWeak auth mechanisms, missing token validationSend requests without tokens, with expired tokens, with manipulated JWTs
3Broken Object Property AuthUser can modify fields they shouldn't (mass assignment)Send extra fields in POST/PUT (role, isAdmin, price)
4Unrestricted Resource ConsumptionNo rate limiting, allows DoSSend 1000 requests/second, check if throttled
5Broken Function Level AuthRegular user can access admin endpointsTry admin routes with regular user tokens
6Unrestricted Access to Sensitive FlowsNo protection on critical flows (checkout, password reset)Automate critical flows without CAPTCHA/limits
7Server-Side Request ForgeryAPI fetches attacker-controlled URLsPass internal URLs (localhost, metadata endpoints) in URL params
8Security MisconfigurationVerbose errors, default credentials, CORS misconfiguredCheck error responses, CORS headers, default passwords
9Improper Inventory ManagementOld API versions still exposed, undocumented endpointsScan for /v1/, /api-old/, /internal/ paths
10Unsafe Consumption of APIsYour API trusts third-party APIs blindlyTest with malicious responses from mocked third-party APIs

Practical Security Tests

Test 1: BOLA (the most common vulnerability)

    // Test: Can user A access user B's order?
// Login as User A, get their token
const tokenA = await login('[email protected]', 'password')

// Try to access User B's order with User A's token
const res = await fetch('/api/orders/user-b-order-id', {
  headers: { Authorization: `Bearer ${tokenA}` },
})

// PASS: should return 403 Forbidden
// FAIL: returns 200 with User B's order data
expect(res.status).toBe(403)

Test 2: Mass Assignment

    // Test: Can a user set themselves as admin?
const res = await fetch('/api/users/me', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${userToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Legit Update',
    role: 'admin',        // Should be ignored
    isVerified: true,     // Should be ignored
  }),
})

const user = await res.json()
// PASS: role and isVerified unchanged
// FAIL: user is now admin
expect(user.role).toBe('user')
expect(user.isVerified).toBe(false)

Test 3: Rate Limiting

    // Test: Does the API throttle excessive requests?
const results = []
for (let i = 0; i < 100; i++) {
  const res = await fetch('/api/login', {
    method: 'POST',
    body: JSON.stringify({ email: '[email protected]', password: 'wrong' }),
  })
  results.push(res.status)
}

// PASS: some requests return 429 (Too Many Requests)
// FAIL: all 100 return 401 (no rate limiting)
expect(results.filter(s => s === 429).length).toBeGreaterThan(0)

API Security Testing Tools

ToolTypePriceBest for
OWASP ZAPDAST scannerFree (open source)Automated scanning in CI/CD
Burp SuiteProxy + scannerFree (Community) / $449/yr (Pro)Manual penetration testing
PostmanAPI clientFree / $14/user/moManual test collections
42CrunchAPI-specific auditFree tier / customOpenAPI spec security audit
StackHawkCI/CD DASTFree tier / $35/moAutomated security in pipelines

Security Testing vs Security Monitoring

Security testing runs before deployment. But attackers don't wait for your test schedule. You need runtime monitoring to detect anomalies in production:

  • Spike in 401/403 errors → possible brute force or credential stuffing attack
  • Spike in 400 errors → possible injection attempt or fuzzing
  • Unusual traffic patterns → possible enumeration or scraping

Nurbak Watch monitors error rates per endpoint in real-time. When /api/login suddenly gets 500 401s in 60 seconds, you get a WhatsApp alert in under 10 seconds — not a security report next quarter.

    // instrumentation.ts
import { initWatch } from '@nurbak/watch'

export function register() {
  initWatch({
    apiKey: process.env.NURBAK_WATCH_KEY,
  })
}

Free during beta. Every endpoint monitored. Error rate spikes detected instantly.

Related Articles