Expertise

API Security & Penetration Testing

Swagger is your worst enemy. APIs expose more than you think.

API security assessments are delivered by Vid Grosek, Slovenia's first OSCE3 and OSCP+ certified penetration tester, through Telprom d.o.o. in Ljubljana. APIs have become the primary attack surface for most applications. And most developers publish complete documentation on how to attack them. Swagger/OpenAPI specs, debug endpoints, older API versions - all of this is a roadmap for attackers.

OWASP API Security Top 10

Understanding the most common API vulnerabilities:

API1: Broken Object Level Authorization (BOLA)

Most common critical API vulnerability. API doesn't verify if user has rights to access requested object.

  • Example: GET /api/users/123/orders - changing 123 to 124 reveals another user's orders
  • Variations: GUIDs instead of IDs aren't a solution - often predictable or leaked elsewhere
  • Testing: Systematically changing all identifiers in requests

API2: Broken Authentication

Incorrect implementation of authentication mechanisms.

  • JWT without signature validation - Server accepts any token
  • Algorithm confusion - Changing RS256 to HS256, signing with public key
  • Weak secrets - JWT signed with weak key, crackable offline
  • Token leakage - Tokens in URLs, logs, error messages

API3: Broken Object Property Level Authorization

API exposes more object properties than it should, or allows modification of protected properties.

  • Excessive data exposure: API returns all attributes including sensitive ones (password hash, internal IDs)
  • Mass assignment: Adding extra fields to request (role: "admin", balance: 99999)

API4: Unrestricted Resource Consumption

Lack of resource consumption limits.

  • No rate limiting: Enables brute force, credential stuffing, DoS
  • Unbounded queries: SELECT * without LIMIT, GraphQL without depth limits
  • Large file uploads: Disk or memory exhaustion

API5: Broken Function Level Authorization

Administrative functions accessible to regular users.

  • Hidden admin endpoints: /api/admin/users, /api/internal/config
  • HTTP method tampering: GET works, POST/DELETE also - without authorization
  • Parameter manipulation: Adding admin=true to request

JWT (JSON Web Token) Attacks

JWT is a standard for authentication, but often incorrectly implemented. The same session and authentication flaws also surface during web application penetration testing.

JWT Structure

Header.Payload.Signature - Base64 encoded, not encrypted!

Attacks

  • Algorithm None: Changing algorithm to "none", removing signature
  • Algorithm Confusion: RS256 → HS256, signing with public key as secret
  • Key ID Injection: kid parameter for path traversal or SQL injection
  • JWK Injection: Including attacker's key in jku/jwk header
  • Weak Secret Brute Force: hashcat/john for cracking HS256 secrets
  • Token Expiry: Accepting expired tokens, too long exp

Protection

  • Whitelist algorithms - don't accept "none" or unexpected ones
  • Strong secrets for HS256 (32+ random bytes)
  • Short exp times, refresh tokens
  • Validate all claims (iss, aud, exp, nbf)

OAuth 2.0 Vulnerabilities

OAuth is a complex protocol with many opportunities for mistakes.

Authorization Code Flow Attacks

  • Open Redirect: Manipulating redirect_uri to steal authorization code
  • CSRF: Missing state parameter enables account linking attacks
  • Code Reuse: Authorization code usable multiple times
  • Scope Upgrade: Requesting higher scope than allowed

Implicit Flow Problems

  • Token in URL: Exposed in Referer header, browser history
  • Token Leakage: XSS on redirect URI page steals token
  • Mix-up Attack: Attacker substitutes authorization server

Client Credentials Mistakes

  • Hardcoded secrets: client_secret in frontend code, mobile apps
  • Insufficient client validation: Accepting requests without client auth

GraphQL Specific Vulnerabilities

GraphQL brings new attack vectors that REST doesn't have. In larger engagements I chain them with Active Directory attacks and Red Team operations.

Introspection

Automatic documentation of entire schema - namespace of all types, fields, mutations.

  • Attack: Query __schema for complete API description
  • Defense: Disable introspection in production

Query Complexity Attacks

  • Deep nesting: Recursive queries (user { friends { friends { friends... }}})
  • Batching: Many operations in one request
  • Aliases: Same query multiple times with different aliases
  • Fragments: Fragments to increase complexity

Injection

  • SQL Injection: In arguments that go to database
  • NoSQL Injection: Especially with MongoDB backends

GraphQL Protection

  • Disable introspection in production
  • Implement query depth and complexity limits
  • Rate limiting per operation, not just per endpoint
  • Field-level authorization

Discovering Hidden APIs

I don't just test documented endpoints.

Discovery Techniques

  • Path fuzzing: /api/v1/users, /api/v2/users, /api/internal/users
  • Version discovery: Older API versions without security patches
  • Debug endpoints: /debug, /test, /swagger, /api-docs, /graphiql
  • JavaScript analysis: API endpoints in frontend code
  • Mobile app reversing: API calls in mobile application
  • Wayback Machine: Old documentation versions, deprecated endpoints

Wordlists

  • SecLists API wordlists
  • Custom wordlists from documentation, frontend code
  • Intelligent fuzzing based on discovered endpoints

Rate Limiting Bypass

Rate limiting is often implemented incorrectly.

Bypass Techniques

  • IP rotation: Different IP addresses (proxy, VPN, cloud functions)
  • Header manipulation: X-Forwarded-For, X-Real-IP spoofing
  • Endpoint variation: /api/login, /api/Login, /api/login/, /api//login
  • Parameter pollution: email=a@b.com&email=c@d.com
  • Unicode normalization: admin vs ɑdmin
  • Case variation: admin@domain.com vs Admin@domain.com

My Approach to API Testing

  1. Reconnaissance: Gathering all available documentation, swagger specs, postman collections
  2. Mapping: All endpoints, parameters, authentication mechanisms
  3. Authentication testing: JWT, OAuth, session management
  4. Authorization testing: BOLA, BFLA on every endpoint
  5. Input validation: Injection, type confusion, boundary testing
  6. Business logic: Workflow bypass, race conditions
  7. Rate limiting: Brute force, enumeration possibilities

Frequently Asked Questions

Why is API security testing important?

APIs expose your business logic directly. Unlike web interfaces, APIs often lack rate limiting, proper authorization checks, and input validation. Common issues include BOLA/IDOR (accessing other users' data), broken authentication, JWT vulnerabilities, and mass data exposure through unrestricted endpoints.

What is BOLA/IDOR and why is it the #1 API vulnerability?

BOLA (Broken Object Level Authorization) or IDOR means an API lets you access resources belonging to other users by simply changing an ID parameter. It's the #1 API vulnerability because it's extremely common, easy to exploit, and often exposes sensitive data at scale.

What is a JWT algorithm confusion attack?

Algorithm confusion is an attack where the attacker changes the JWT signing algorithm from RS256 to HS256 and signs the token with the server's public key as the secret, allowing valid tokens to be forged. The defense is to whitelist allowed algorithms and strictly validate the token header.

How do I disable GraphQL introspection?

GraphQL introspection exposes the entire API schema - all types, fields, and mutations - so it should be disabled in production in the GraphQL server configuration, alongside query depth and complexity limits and field-level authorization.

What is the difference between BFLA and BOLA?

BOLA (Broken Object Level Authorization) means accessing other users' objects by manipulating IDs, while BFLA (Broken Function Level Authorization) means accessing administrative functions and endpoints that a regular user should not be able to reach.

Need an API Security Assessment?

Discover vulnerabilities in your REST, GraphQL, and WebSocket APIs before attackers do.