Vulnerability Research

Top 10 API Security Vulnerabilities Every Developer Should Know

FTB
Find The Breach Security Team
· · 15 min read

APIs are the backbone of modern applications — powering mobile apps, single-page frontends, microservice architectures, and third-party integrations. But the same flexibility that makes APIs powerful also makes them prime targets for attackers. In our penetration testing data, API vulnerabilities account for 73% of critical findings in modern applications. This guide walks through the OWASP API Security Top 10, with real-world examples and code-level remediation for each vulnerability class.

Why API Security Deserves Special Attention

Traditional web application security focused on server-rendered HTML pages. The attack surface was relatively contained: forms, URL parameters, and cookies. Modern API-first architectures fundamentally change this equation:

  • Expanded attack surface — A typical SaaS application exposes 50-200 API endpoints, each accepting structured data (JSON, GraphQL queries, protobuf) that must be validated independently
  • Direct data access — APIs return raw data without the presentation layer that might obscure sensitive fields in HTML responses
  • Machine-to-machine traffic — APIs are designed for programmatic access, making automated exploitation trivially easy once a vulnerability is found
  • Authentication complexity — APIs use tokens (JWT, OAuth), API keys, and certificate-based auth — each with distinct failure modes

The OWASP API Security Project maintains a dedicated Top 10 list specifically for API risks. Let's examine each one in depth.

API1: Broken Object-Level Authorization (BOLA)

BOLA is the single most common API vulnerability — and the most dangerous. It occurs when an API endpoint accepts an object identifier (ID, UUID, slug) from the client but fails to verify that the authenticated user has permission to access that specific object.

How It Works

# User A is authenticated and requests their own invoice
GET /api/v2/invoices/1001
Authorization: Bearer <user_a_token>
→ 200 OK { "id": 1001, "amount": 250.00, "user": "user_a" }

# User A changes the ID to access User B's invoice
GET /api/v2/invoices/1002
Authorization: Bearer <user_a_token>
→ 200 OK { "id": 1002, "amount": 15000.00, "user": "user_b" }  ← BOLA!

Why It's So Prevalent

Most frameworks don't enforce object-level authorization automatically. Developers must explicitly check ownership for every endpoint that accepts an object identifier. In applications with hundreds of endpoints, it's easy to miss a few — and attackers only need one.

Remediation

# Python/Flask — Always verify object ownership
@app.route('/api/v2/invoices/<int:invoice_id>')
@require_auth
def get_invoice(invoice_id):
    invoice = Invoice.query.get_or_404(invoice_id)
    if invoice.user_id != current_user.id:
        abort(403)  # Forbidden — not your resource
    return jsonify(invoice.to_dict())

# Better: Use a query that scopes to the current user
@app.route('/api/v2/invoices/<int:invoice_id>')
@require_auth
def get_invoice(invoice_id):
    invoice = Invoice.query.filter_by(
        id=invoice_id,
        user_id=current_user.id
    ).first_or_404()
    return jsonify(invoice.to_dict())

API2: Broken Authentication

Authentication mechanisms in APIs are frequently misconfigured or implemented with subtle flaws. Unlike web apps with session cookies, APIs typically use token-based authentication — introducing unique failure modes.

Common Authentication Failures

  • JWT algorithm confusion — Accepting alg: none or allowing algorithm switching from RS256 to HS256 (using the public key as HMAC secret)
  • Missing token expiration — JWTs without exp claims that remain valid indefinitely
  • Weak API key generation — Sequential or predictable API keys that can be enumerated
  • No rate limiting on auth endpoints — Allowing unlimited login attempts enables credential stuffing
  • Token leakage in URLs — API keys or tokens passed as query parameters, logged in server access logs
# Testing for JWT "none" algorithm vulnerability
import jwt, json, base64

# Decode the existing token
token = "eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4ifQ.signature"
header = json.loads(base64.urlsafe_b64decode(token.split('.')[0] + '=='))

# Forge a token with "none" algorithm
header['alg'] = 'none'
new_header = base64.urlsafe_b64encode(json.dumps(header).encode()).rstrip(b'=')
payload = token.split('.')[1]
forged_token = f"{new_header.decode()}.{payload}."

# If the API accepts this token, it's vulnerable

Remediation

  • Explicitly specify allowed algorithms when verifying JWTs: jwt.decode(token, key, algorithms=["RS256"])
  • Enforce short token expiration (15 minutes for access tokens) with refresh token rotation
  • Implement rate limiting on all authentication endpoints (5 attempts per minute per IP/account)
  • Never pass tokens in URL query parameters — always use the Authorization header

API3: Broken Object Property-Level Authorization

This vulnerability combines two related issues from the previous OWASP API Top 10: excessive data exposure and mass assignment. It occurs when APIs expose object properties that the user shouldn't be able to read or modify.

Excessive Data Exposure

# API returns all user fields, including sensitive ones
GET /api/v2/users/me
→ 200 OK
{
  "id": 42,
  "name": "Jane Doe",
  "email": "jane@example.com",
  "role": "user",           ← Should not be exposed
  "password_hash": "$2b$...", ← Definitely should not be exposed
  "ssn": "123-45-6789",     ← PII leak
  "internal_notes": "..."   ← Internal data leak
}

Mass Assignment

# Attacker adds unauthorized fields to their update request
PUT /api/v2/users/me
Content-Type: application/json
{
  "name": "Jane Doe",
  "role": "admin",          ← Mass assignment — elevating privileges
  "is_verified": true,      ← Mass assignment — bypassing verification
  "credit_balance": 99999   ← Mass assignment — financial manipulation
}

Remediation

# Use explicit serialization — never return raw model objects
class UserResponse(BaseModel):
    id: int
    name: str
    email: str
    # Only include fields the user should see

# Use explicit allow-lists for updates
ALLOWED_UPDATE_FIELDS = {"name", "email", "avatar_url"}

@app.route('/api/v2/users/me', methods=['PUT'])
@require_auth
def update_user():
    data = request.get_json()
    filtered = {k: v for k, v in data.items() if k in ALLOWED_UPDATE_FIELDS}
    current_user.update(**filtered)
    return jsonify(UserResponse.from_orm(current_user))

API4: Unrestricted Resource Consumption

APIs that don't enforce limits on resource consumption are vulnerable to denial of service, cost exhaustion (in cloud environments), and data scraping. This is especially critical for APIs that perform expensive operations like file processing, database queries, or third-party API calls.

Attack Vectors

  • Missing rate limiting — Unlimited requests allow brute-force, scraping, and DoS
  • Unbounded pagination?page_size=1000000 returning the entire database
  • Expensive operations — GraphQL queries requesting deeply nested relationships that generate thousands of database queries
  • File upload abuse — No limits on file size, count, or processing time

Remediation

# Enforce rate limits, pagination bounds, and query complexity
from flask_limiter import Limiter

limiter = Limiter(app, default_limits=["100/minute"])

@app.route('/api/v2/search')
@limiter.limit("20/minute")
def search():
    page_size = min(request.args.get('limit', 20, type=int), 100)  # Cap at 100
    offset = request.args.get('offset', 0, type=int)
    results = db.query(Item).limit(page_size).offset(offset).all()
    return jsonify(results)

API5: Broken Function-Level Authorization

While BOLA is about accessing objects you don't own, broken function-level authorization is about accessing actions you shouldn't be able to perform. This typically manifests as regular users accessing admin endpoints.

# Regular user discovers admin API endpoints
GET /api/v2/admin/users          ← Lists all users
DELETE /api/v2/admin/users/42    ← Deletes a user
POST /api/v2/admin/config        ← Modifies system configuration

# These endpoints exist and are functional, but rely on
# client-side routing to prevent access — not server-side checks

Remediation

  • Implement role-based authorization middleware that runs on every request
  • Deny by default — require explicit authorization decorators for every endpoint
  • Separate admin and user API namespaces with different authentication requirements
  • Log and alert on unauthorized access attempts to admin endpoints

API6: Server-Side Request Forgery (SSRF)

SSRF occurs when an API accepts a URL from the client and makes a server-side request to it. In cloud environments, this is particularly dangerous because the attacker can reach internal services and cloud metadata endpoints.

# Vulnerable endpoint that fetches a URL
POST /api/v2/import
{ "url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/" }

# The server fetches the AWS metadata endpoint and returns IAM credentials
→ 200 OK
{
  "AccessKeyId": "AKIA...",
  "SecretAccessKey": "...",
  "Token": "..."
}

Remediation

  • Maintain an allow-list of permitted domains and protocols
  • Block requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16)
  • Disable HTTP redirects on server-side requests (attackers use redirects to bypass allow-lists)
  • Use IMDSv2 with hop limit of 1 to prevent SSRF-based metadata theft on AWS

API7: Security Misconfiguration

API security misconfigurations are broad, but common patterns include exposing debug endpoints in production, missing security headers, permissive CORS, and verbose error messages that leak implementation details.

Critical Misconfigurations

  • CORS wildcard with credentialsAccess-Control-Allow-Origin: * with Access-Control-Allow-Credentials: true
  • Debug mode in production — Stack traces, SQL queries, and internal paths in error responses
  • Exposed API documentation — Swagger/OpenAPI spec accessible without authentication at /api/docs, /swagger.json
  • Missing TLS — API traffic over HTTP, or accepting TLS 1.0/1.1
  • Default credentials — Admin panels or management APIs using default passwords

For a broader view of infrastructure misconfigurations, see our guide on cloud security misconfigurations across AWS, Azure, and GCP.

API8: Lack of Protection from Automated Threats

APIs are inherently machine-friendly, which means bot-driven attacks are harder to distinguish from legitimate traffic. This category covers credential stuffing, scraping, inventory manipulation, and automated abuse of business logic.

Remediation Strategy

  1. Rate limiting — Implement per-user, per-IP, and per-endpoint rate limits
  2. Behavioral analysis — Track request patterns and flag anomalous behavior (e.g., sequential ID enumeration)
  3. CAPTCHA for sensitive operations — Add human-verification challenges for password resets, account creation, and high-value transactions
  4. Device fingerprinting — Identify and throttle requests from automated tools

API9: Improper Inventory Management

Organizations frequently lose track of which API versions are deployed, which endpoints are deprecated, and which environments are accessible from the internet. Shadow APIs — undocumented endpoints that developers created for testing or internal use — are a major blind spot.

# Common shadow API discovery patterns
/api/v1/users          ← Old version, still accessible, fewer security controls
/api/v2/users          ← Current version with proper auth
/api/beta/users        ← Beta endpoint with debug logging enabled
/api/internal/metrics  ← Internal monitoring endpoint, no auth required
/graphql               ← GraphQL endpoint with introspection enabled

Remediation

  • Maintain a complete API inventory with version, owner, environment, and deprecation status
  • Use API gateways to enforce that only documented endpoints are accessible
  • Disable previous API versions or apply the same security controls as current versions
  • Run regular penetration tests that include API discovery and enumeration

API10: Unsafe Consumption of Third-Party APIs

When your API consumes data from third-party services, it inherits those services' security posture. If a third-party API is compromised or returns malicious data, your application becomes the attack vector.

Risks

  • Unvalidated third-party data — Trusting and rendering data from external APIs without sanitization
  • Following redirects blindly — Third-party APIs redirecting your server to internal resources (SSRF chain)
  • Excessive trust — Not validating TLS certificates or data schemas from partners

Remediation

  • Validate and sanitize all data received from third-party APIs before processing
  • Implement circuit breakers and timeouts for third-party API calls
  • Pin TLS certificates for critical third-party integrations
  • Apply the same input validation rules to third-party data as you do to user input

Testing Your APIs with Find The Breach

Comprehensive API security testing requires both automated scanning and manual analysis. Find The Breach combines both approaches — automated tools identify common vulnerability patterns, while AI-assisted analysis reduces false positives and identifies complex business logic flaws.

# Scan your API for OWASP API Top 10 vulnerabilities
$ curl -X POST https://api.findthebreach.com/v1/scans \
    -H "Authorization: Bearer $FTB_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "target": "https://api.yourapp.com",
      "scan_type": "full",
      "api_spec": "https://api.yourapp.com/openapi.json",
      "auth": {
        "type": "bearer",
        "token": "$API_TOKEN"
      },
      "notify": ["security@yourcompany.com"]
    }'

Test your APIs for the OWASP Top 10

Run a free scan to discover BOLA, broken authentication, and other critical API vulnerabilities in your endpoints.

Start Free API Scan

Related Articles

Subscribe to Our Security Newsletter

Get the latest vulnerability research, penetration testing guides, and product updates delivered to your inbox every week. No spam — just actionable security insights.

Unsubscribe anytime. Read our privacy policy.