<!-- AUTO-GENERATED by export-skills.py — DO NOT EDIT -->
---
name: owasp-api-top10
description: OWASP API Security Top 10 (2023) risk identification, prevention patterns, and testing guidance for securing REST/GraphQL APIs
---

# OWASP API Security Top 10 (2023)

## Overview

The OWASP API Security Top 10 is a standardized awareness document for API-specific security risks. Unlike the general OWASP Top 10 (which focuses on web applications), this list addresses the unique attack surface of APIs -- broken object-level authorization, mass assignment, rate limiting gaps, and more. APIs are the backbone of modern architectures (microservices, mobile backends, SaaS integrations), making them a primary target for attackers.

This skill covers all 10 risks from the 2023 edition, provides concrete attack scenarios, and maps each risk to prevention patterns applicable to Python/FastAPI codebases.

## When to Use This Skill

- Designing or reviewing API endpoints (REST, GraphQL, gRPC)
- Performing threat modeling on microservice architectures
- Conducting API security code reviews or penetration tests
- Building authorization middleware or rate-limiting layers
- Creating an API security checklist for CI/CD pipelines
- Evaluating third-party API integrations for security posture

## How It Works

### Step 1: Inventory API Endpoints

Catalog every API endpoint in the system. Use OpenAPI/Swagger specs as the source of truth. For each endpoint, document the HTTP method, path, required authentication, authorization scope, and data sensitivity classification.

```bash
# Extract all routes from a FastAPI app
python -c "
from app.main import app
for route in app.routes:
    if hasattr(route, 'methods'):
        for method in route.methods:
            print(f'{method:7s} {route.path}')
"
```

### Step 2: Classify Data Sensitivity

Map each endpoint's request/response payloads to sensitivity tiers:

| Tier | Examples | Controls Required |
|------|----------|-------------------|
| Critical | Passwords, tokens, PII, financial data | Encryption at rest + transit, audit logging, field-level access control |
| High | Email, phone, user preferences | Access control, audit logging |
| Medium | Public profile data, non-sensitive metadata | Authentication required |
| Low | Health checks, public catalog data | Rate limiting only |

### Step 3: Map Authentication and Authorization Requirements

For every endpoint, define:
- **AuthN**: Which authentication mechanism (JWT, API key, OAuth2, mTLS)?
- **AuthZ**: Which authorization model (RBAC, ABAC, ReBAC)? What resource ownership checks are needed?
- **Scope**: What OAuth2 scopes or permission claims are required?

### Step 4: Test with Security Scanning Tools

Run automated scans using OWASP ZAP, Burp Suite, or Nuclei against staging environments:

```bash
# OWASP ZAP API scan with OpenAPI spec
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-api-scan.py \
  -t https://staging.example.com/openapi.json \
  -f openapi \
  -r zap-report.html

# Nuclei scan for API-specific vulnerabilities
nuclei -u https://staging.example.com/api \
  -t http/vulnerabilities/ \
  -t http/misconfiguration/ \
  -severity critical,high
```

### Step 5: Implement Controls for Each Risk

Apply the prevention patterns below for each of the 10 risks. Prioritize by likelihood and impact in your specific architecture.

---

## The 10 API Security Risks

### API1:2023 - Broken Object Level Authorization (BOLA)

**Description:** APIs expose endpoints that handle object identifiers, creating a wide attack surface. An attacker substitutes the ID of a resource they own with the ID of a resource belonging to another user. Lack of authorization checks lets the attacker access or modify the target resource.

**Attack Scenario:** `GET /api/v1/invoices/12345` -- attacker changes `12345` to `12346` and receives another tenant's invoice because the endpoint only checks authentication, not ownership.

**Prevention:**
- Enforce object-level authorization on every endpoint that accesses a resource by ID
- Use the authenticated user's session/token to derive tenant context -- never trust client-supplied tenant IDs
- Write authorization as a reusable dependency, not inline per-route logic

### API2:2023 - Broken Authentication

**Description:** Authentication mechanisms are implemented incorrectly, allowing attackers to compromise tokens, exploit implementation flaws, or assume other users' identities.

**Attack Scenario:** Credential stuffing against `/api/v1/auth/login` with no rate limiting or account lockout. Weak JWT validation accepts tokens signed with `alg: none`.

**Prevention:**
- Use established libraries for JWT validation (python-jose, PyJWT) with explicit algorithm allow-lists
- Implement rate limiting on authentication endpoints (stricter than general endpoints)
- Enforce MFA for sensitive operations
- Rotate and expire tokens with short TTLs; use refresh token rotation

### API3:2023 - Broken Object Property Level Authorization

**Description:** APIs expose object properties that the user should not be able to read (excessive data exposure) or modify (mass assignment). This combines the former API3 (Excessive Data Exposure) and API6 (Mass Assignment) from the 2019 edition.

**Attack Scenario:** `GET /api/v1/users/me` returns `{"name": "Alice", "role": "user", "internal_credit_score": 780}`. Or: `PUT /api/v1/users/me` with `{"role": "admin"}` succeeds because the endpoint blindly accepts all fields.

**Prevention:**
- Define explicit response schemas that exclude sensitive internal fields
- Use allow-lists for writable fields on update endpoints (never pass raw request body to ORM)
- Implement field-level authorization for sensitive properties

### API4:2023 - Unrestricted Resource Consumption

**Description:** APIs do not limit the size or number of resources that can be requested, leading to denial of service, brute-force attacks, or cost escalation (e.g., SMS/email flooding).

**Attack Scenario:** `GET /api/v1/products?page_size=999999` returns the entire catalog in one response. Or: `/api/v1/otp/send` is called 10,000 times with no rate limit, running up SMS costs.

**Prevention:**
- Enforce max page sizes and default pagination on all list endpoints
- Implement rate limiting per user/IP/API key with sliding windows
- Set request body size limits and query complexity limits (GraphQL depth/breadth)
- Budget external API calls (SMS, email) with per-user quotas

### API5:2023 - Broken Function Level Authorization

**Description:** Attackers send API calls to endpoints they should not have access to. These may be administrative functions or endpoints of a different user role. The API relies on the client to enforce access control.

**Attack Scenario:** Regular user calls `DELETE /api/v1/admin/users/42` or `POST /api/v1/admin/config` -- admin endpoints exist but authorization middleware is missing or misconfigured.

**Prevention:**
- Deny by default -- require explicit authorization decorators on every route
- Separate admin and user API routers with distinct middleware stacks
- Implement role-based route guards as framework middleware, not per-handler logic

### API6:2023 - Unrestricted Access to Sensitive Business Flows

**Description:** APIs expose business flows (purchasing, posting reviews, booking) that can be automated and abused at scale without proper anti-automation controls.

**Attack Scenario:** Bot purchases all limited-edition items via `/api/v1/checkout` faster than human users. Or: automated review posting to manipulate ratings.

**Prevention:**
- Identify business-critical flows and add anti-automation (CAPTCHA, device fingerprinting)
- Implement velocity checks (e.g., max 3 purchases per user per hour)
- Monitor for anomalous patterns (burst traffic from single user/IP)

### API7:2023 - Server Side Request Forgery (SSRF)

**Description:** An API fetches a remote resource based on a user-supplied URL without validating the target. Attackers use SSRF to access internal services, cloud metadata endpoints, or port-scan internal networks.

**Attack Scenario:** `POST /api/v1/webhooks {"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}` -- the server fetches AWS credentials from the metadata service.

**Prevention:**
- Validate and sanitize all user-supplied URLs against an allow-list of domains/protocols
- Block requests to private IP ranges (10.x, 172.16-31.x, 192.168.x, 169.254.x, localhost)
- Use a dedicated egress proxy for outbound requests with URL filtering
- Disable HTTP redirects or validate the redirect target

### API8:2023 - Security Misconfiguration

**Description:** APIs and their supporting infrastructure (API gateways, cloud services, frameworks) are misconfigured, leaving default credentials, unnecessary HTTP methods, verbose error messages, or missing security headers.

**Attack Scenario:** CORS set to `Access-Control-Allow-Origin: *` with credentials. Debug mode enabled in production exposes stack traces. TLS 1.0/1.1 still enabled.

**Prevention:**
- Harden CORS (specific origins, no wildcard with credentials)
- Disable debug/verbose error modes in production
- Enforce TLS 1.2+ with strong cipher suites
- Remove default credentials and unnecessary HTTP methods (TRACE, OPTIONS)
- Automate configuration audits in CI/CD

### API9:2023 - Improper Inventory Management

**Description:** Organizations lose track of API versions, deprecated endpoints, and shadow APIs. Old or unmanaged API versions remain exposed without security patches.

**Attack Scenario:** Production runs API v3 with proper auth, but v1 (`/api/v1/users`) is still accessible with weaker authentication and returns more data than v3.

**Prevention:**
- Maintain a machine-readable API inventory (OpenAPI specs in version control)
- Decommission old API versions with hard deadlines and client migration plans
- Use API gateways to enforce version routing and block deprecated versions
- Scan for undocumented endpoints (shadow API discovery)

### API10:2023 - Unsafe Consumption of APIs

**Description:** Developers trust data from third-party APIs without validation. If a third-party API is compromised or returns malicious data, the consuming application becomes vulnerable.

**Attack Scenario:** Application consumes a partner API that returns user display names. A compromised partner injects `<script>` tags in names, causing stored XSS when rendered.

**Prevention:**
- Validate and sanitize all data received from third-party APIs
- Apply the same input validation rules as for user input
- Use allow-lists for expected data formats and reject unexpected structures
- Implement circuit breakers and timeouts for external API calls

---

## Examples

### Example 1: Detecting and Preventing BOLA (API1) in FastAPI

```python
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth import get_current_user, CurrentUser
from app.database import get_db

router = APIRouter(prefix="/api/v1/invoices", tags=["invoices"])


# BAD: No ownership check -- vulnerable to BOLA
@router.get("/{invoice_id}")
async def get_invoice_insecure(invoice_id: int, db: AsyncSession = Depends(get_db)):
    invoice = await db.get(Invoice, invoice_id)
    if not invoice:
        raise HTTPException(status_code=404)
    return invoice  # Any authenticated user can access any invoice


# GOOD: Ownership check prevents BOLA
@router.get("/{invoice_id}")
async def get_invoice_secure(
    invoice_id: int,
    current_user: CurrentUser = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    invoice = await db.get(Invoice, invoice_id)
    if not invoice:
        raise HTTPException(status_code=404)

    # Enforce object-level authorization
    if invoice.tenant_id != current_user.tenant_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Not authorized to access this resource",
        )
    return InvoiceResponse.model_validate(invoice)  # Explicit response schema
```

### Example 2: Rate Limiting for API4 (Python/FastAPI with SlowAPI)

```python
from fastapi import FastAPI, Request
from slowapi import Limiter
from slowapi.util import get_remote_address
from slowapi.errors import RateLimitExceeded
from slowapi.middleware import SlowAPIMiddleware

limiter = Limiter(
    key_func=get_remote_address,
    default_limits=["100/minute"],
    storage_uri="redis://localhost:6379/0",
)

app = FastAPI()
app.state.limiter = limiter
app.add_middleware(SlowAPIMiddleware)


# Stricter limit on authentication endpoints (API2 + API4)
@app.post("/api/v1/auth/login")
@limiter.limit("5/minute")
async def login(request: Request):
    ...


# Stricter limit on sensitive business flows (API6)
@app.post("/api/v1/checkout")
@limiter.limit("3/minute")
async def checkout(request: Request):
    ...


# Standard limit on data endpoints with pagination enforcement (API4)
@app.get("/api/v1/products")
@limiter.limit("60/minute")
async def list_products(request: Request, page: int = 1, page_size: int = 20):
    MAX_PAGE_SIZE = 100
    page_size = min(page_size, MAX_PAGE_SIZE)  # Enforce ceiling
    ...
```

### Example 3: API Inventory Management with OpenAPI Spec

```yaml
# openapi-inventory.yaml -- central API inventory for API9 prevention
openapi: "3.1.0"
info:
  title: "FAOS Platform API Inventory"
  version: "2024-01-15"
  description: "Canonical inventory of all active API endpoints"

paths:
  /api/v3/users:
    get:
      summary: "List users (current version)"
      x-api-status: active
      x-data-classification: high
      x-auth-required: true
      x-auth-scopes: ["users:read"]

  /api/v1/users:
    get:
      summary: "List users (DEPRECATED)"
      x-api-status: deprecated
      x-deprecation-date: "2023-06-01"
      x-sunset-date: "2024-03-01"
      x-migration-guide: "https://docs.example.com/migrate-v1-v3"
      deprecated: true

# CI check: fail build if any path has x-api-status: deprecated past x-sunset-date
```

```bash
# CI script to enforce API inventory hygiene
#!/usr/bin/env bash
set -euo pipefail

TODAY=$(date +%Y-%m-%d)
DEPRECATED=$(yq '.paths | to_entries[] |
  select(.value[].x-api-status == "deprecated") |
  select(.value[]."x-sunset-date" < env(TODAY)) |
  .key' openapi-inventory.yaml)

if [ -n "$DEPRECATED" ]; then
  echo "ERROR: The following deprecated APIs are past their sunset date:"
  echo "$DEPRECATED"
  exit 1
fi
```

## Best Practices

### Do This

- Enforce object-level authorization on every endpoint that accepts a resource identifier
- Use explicit Pydantic response models to control exactly which fields are exposed
- Implement rate limiting at the API gateway and application layers (defense in depth)
- Maintain a versioned OpenAPI spec as the single source of truth for your API surface
- Log all authorization failures with sufficient context for incident response
- Validate all URLs before making server-side requests (SSRF prevention)
- Apply pagination with enforced maximum page sizes on all list endpoints
- Treat third-party API responses with the same suspicion as user input

### Don't Do This

- Do not rely solely on authentication to protect resources -- AuthN is not AuthZ
- Do not expose internal object IDs without authorization gates
- Do not pass raw request bodies to ORM update methods (mass assignment)
- Do not set CORS to `*` with `allow_credentials=True`
- Do not leave deprecated API versions running without a sunset plan
- Do not trust client-side rate limiting or client-supplied tenant/user IDs
- Do not make outbound HTTP requests to user-supplied URLs without validation
- Do not return stack traces or internal error details in production responses

## Security Checklist

### Authorization (API1, API3, API5)
- [ ] Every endpoint accessing a resource by ID includes ownership/tenant verification
- [ ] Response schemas explicitly list returned fields (no ORM model passthrough)
- [ ] Update endpoints use allow-listed writable fields (no mass assignment)
- [ ] Admin endpoints are behind role-based authorization middleware
- [ ] Default-deny policy: routes without explicit auth decorators are blocked

### Authentication (API2)
- [ ] JWT validation uses explicit algorithm allow-list (no `alg: none`)
- [ ] Authentication endpoints have stricter rate limits than data endpoints
- [ ] Token TTLs are short (15-30 minutes for access tokens)
- [ ] Refresh token rotation is implemented (one-time use refresh tokens)
- [ ] Password reset and OTP endpoints have brute-force protection

### Resource Consumption (API4, API6)
- [ ] All list endpoints enforce maximum page sizes
- [ ] Rate limiting is configured per user/IP with sliding windows
- [ ] Request body size limits are enforced at the gateway and application level
- [ ] Sensitive business flows have anti-automation controls (CAPTCHA, velocity checks)
- [ ] External API call budgets are enforced (SMS, email quotas)

### Infrastructure (API7, API8)
- [ ] SSRF protections block private IP ranges and metadata endpoints
- [ ] CORS is configured with specific allowed origins (no wildcard + credentials)
- [ ] TLS 1.2+ enforced; TLS 1.0/1.1 disabled
- [ ] Debug mode and verbose error responses are disabled in production
- [ ] Security headers present (X-Content-Type-Options, X-Frame-Options, CSP)

### Inventory and Integration (API9, API10)
- [ ] API inventory is maintained in version control (OpenAPI specs)
- [ ] Deprecated API versions have documented sunset dates and migration plans
- [ ] Shadow API discovery scans run periodically
- [ ] Third-party API responses are validated and sanitized before use
- [ ] Circuit breakers and timeouts are configured for all external API calls

## Related Skills

- @api-security-patterns -- Detailed implementation patterns for API security controls
- @owasp-top10 -- General web application security risks (broader than API-specific)
- @cwe-sans-top25 -- Software weakness classification with CWE IDs for root-cause analysis

## Additional Resources

- [OWASP API Security Top 10 (2023)](https://owasp.org/API-Security/editions/2023/en/0x11-t10/)
- [OWASP API Security Project](https://owasp.org/www-project-api-security/)
- [OWASP API Security Testing Guide](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/12-API_Testing/)
- [NIST SP 800-204: Security Strategies for Microservices](https://csrc.nist.gov/publications/detail/sp/800-204/final)
- [CWE/SANS Top 25 Mapping to OWASP API Top 10](https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html)

<!-- Source: .faos/custom/skills/security/owasp-api-top10/SKILL.md -->
