Skip to content

API Testing

Source: PortSwigger Web Security Academy Author: Johan Beysen


1. What Is an API?

API = Application Programming Interface — an interface through which applications communicate with each other via structured HTTP requests and responses.


2. Recon — Finding API Endpoints

Via a Burp Crawl

Browse or crawl the website until you come across an API request in Burp, e.g.:

PATCH /api/user/wiener HTTP/2

Send it to Repeater and work backward by dropping arguments:

PATCH /api/user     → 400 Error (no identifier)
PATCH /api          → 302 Found ← Bingo! Found the API root

Right-click the response → Open in browser → API documentation is visible.

Known Documentation Endpoints

/api
/swagger/index.html
/openapi.json
/api-docs
/graphql
/.well-known/openapi.json

Exploring the base path

If you find /api/swagger/v1/users/123, also try:

  • /api/swagger/v1
  • /api/swagger
  • /api

Use Intruder with a wordlist of common API paths.


3. Interacting with API Endpoints

By sending API requests to Repeater and varying them, you learn how the API reacts.

OPTIONS Method

Send an OPTIONS request on each endpoint to see which methods are allowed:

OPTIONS /api/products/1 HTTP/2

HTTP/2 200 OK
Allow: GET, POST, PUT, DELETE, PATCH

What You Learn from OPTIONS

1. Allowed HTTP methods

Allow: GET, POST, PUT, DELETE, PATCH
→ DELETE is possible — try deleting a product without auth!

2. CORS configuration

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Credentials: true
→ Check for a CORS misconfiguration!

3. Hidden methods

Request: GET /api/admin  → 403 Forbidden
Request: OPTIONS /api/admin → Allow: GET, POST, DELETE, TRACE
Request: TRACE /api/admin   → 200 OK ✓
→ TRACE may be unprotected!

4. Content-Type requirements

Accept: application/json, application/xml
→ The server accepts XML → try XXE!

5. API version info

API-Version: 2.1.3
Supported-Versions: 1.0, 2.0, 2.1
→ Older versions may have vulnerabilities!

HTTP Methods Overview

Method What you're testing Typical risk
OPTIONS Which methods are allowed Hidden/unprotected methods
HEAD Like GET but without a body Sometimes different AC than GET
TRACE Echoes the request Info disclosure, XST
CONNECT Tunnel setup SSRF possible
PATCH vs PUT Partial vs full update Different AC rules

Reconnaissance Flow

# 1. Try OPTIONS on each endpoint
OPTIONS /api/users
OPTIONS /api/admin
OPTIONS /api/products/1

# 2. Compare Allow headers
/api/users  → Allow: GET, POST
/api/admin  → Allow: GET, POST, DELETE, PATCH  ← Extra methods!

# 3. Test those extra methods
DELETE /api/admin/users/123  ← Maybe no AC check?

Practical Example

# Step 1: Discovery
OPTIONS /api/products/1/price
→ Allow: GET, PATCH

# Step 2: Test PATCH without auth
PATCH /api/products/1/price
Content-Type: application/json
{"price": 0}
→ 200 OK ← Vulnerability! No AC check on PATCH

4. Server Side Parameter Pollution

Sometimes there are APIs that aren't directly visible but work server-side. To map these out, you need parameters — and you often don't know beforehand what they are.

The trick is to figure out which parameters are possible and manipulate them accordingly.

These can be:

  • Query parameters
  • Form fields
  • Headers
  • URL path parameters

Characters Used

#  → %23  (URL-encoded)
&  → %26  (URL-encoded)
=  → %3D  (URL-encoded)

Burp tip

Ctrl+U or Ctrl+Shift+U in Burp Repeater converts selected text to URL encoding.

Example — Parameter Injection

# Original request
GET /api/userinfo?user=wiener

# Inject an extra parameter via #
GET /api/userinfo?user=wiener%23foo
→ What the server sees: user=wiener#foo
→ Everything after # can be treated as a comment or a second query

# Inject via &
GET /api/userinfo?user=wiener%26admin=true
→ What the server sees: user=wiener&admin=true

Goal

By injecting parameters, you try to manipulate internal server-side parameters that normally aren't reachable via the client.