1. Introduction
In today’s cloud-native, microservices-driven world, APIs (Application Programming Interfaces) form a critical layer in nearly every modern application stack. But with this central role comes a growing number of API security risks, from insecure authentication to data exposure and broken access control. That’s where intentionally vulnerable labs like OWASP crAPI come into play.
OWASP crAPI, short for Completely Ridiculous API, is a deliberately insecure API application created by the Open Worldwide Application Security Project (OWASP) to help developers, testers, and security professionals learn how to identify and exploit common API vulnerabilities in a safe environment.
In this hands-on guide, you’ll learn how to:
- Deploy OWASP crAPI locally using Docker Compose
- Explore its API structure via Swagger/OpenAPI
- Scan for vulnerabilities using OWASP ZAP – a leading open-source web application security scanner
- Understand and intercept Bearer tokens (JWTs) for authenticated API scans
- Troubleshoot common pitfalls when working with API specs and security tools
Whether you’re a DevSecOps engineer, a penetration tester, or a developer learning secure coding, this tutorial will give you a practical walkthrough of modern API security testing workflows using industry-standard tools like Docker, ZAP, and JWT debugging tools such as JWT.io.
✅ If you’re interested in mastering API security or preparing for certifications like OSCP, GWAPT, or APISEC, this guide is a great real-world starting point.

2. Prerequisites
Before diving into the setup of OWASP crAPI and scanning it with OWASP ZAP, you’ll need a few tools and some foundational knowledge. This guide is beginner-friendly but assumes you’re comfortable running commands in a terminal.
✅ Tools You’ll Need
- Docker and Docker Compose
These tools are used to deploy OWASP crAPI quickly and reliably. It’s recommended to run Docker inside a virtual machine (VM) for isolation and easier teardown — especially during testing. On Debian-based systems (e.g., Ubuntu), you can install both with:
sudo apt install docker.io && sudo apt install docker-composeAlternatively, refer to the official Docker installation guide and Docker Compose setup.
- OWASP ZAP (Zed Attack Proxy)
ZAP is an open-source security scanner used for intercepting, mapping, and attacking web and API traffic. It’s best to install and run ZAP locally on your host machine, but it can also be used inside the same VM if preferred.
➜ Download: https://www.zaproxy.org/download/ - A modern web browser (Chrome, Firefox, etc.)
Needed for interacting with the crAPI front-end and optionally configuring a proxy to route traffic through ZAP.
🛠️ Like ZAP, the browser should ideally be run on your local machine, but you can also use everything inside a single VM if needed.
🧠 Knowledge You’ll Benefit From
To get the most out of this walkthrough, a working knowledge of the following concepts will help:
- Docker basics – Understanding containers, volumes, and using
docker-compose - REST APIs – What endpoints are, and how GET/POST requests function
- Bearer authentication and JWTs (JSON Web Tokens) – For accessing protected API routes
- ZAP usage and HTTP proxies – How to configure ZAP as a proxy to inspect traffic
⚠️ If you’re new to any of the above, consider checking out the Docker Getting Started guide and the ZAP User Manual to familiarize yourself with the tools.
3. Setting Up OWASP crAPI with Docker Compose
Getting OWASP crAPI running locally is mostly smooth, but I ran into a few common issues that are worth flagging. This section walks through what worked for me — and what didn’t — so you can avoid the same roadblocks.
3.1 Clone the crAPI Repository
The first thing I tried was downloading the v1.1.5 release ZIP from GitHub, because that’s what was linked on the crAPI develop branch page. However, when I tried to unzip the file, I ran into issues — one of the files was flagged with an “ASCII text file with no line terminators” warning, and the archive didn’t extract cleanly.
It seems that downloading tagged release ZIPs can sometimes cause file encoding or structure problems, especially with Unix-based tooling.
Cloning the repository directly resolved the issue:
git clone https://github.com/OWASP/crAPI.git
cd crAPI⚠️ Even if the documentation points to a ZIP file, it’s best to
git clonethe repo directly to avoid encoding or extraction issues that can break the environment later.
Once inside the deploy/docker directory, I ran:
docker-compose pull
This command pulls all required Docker images from Docker Hub.. It’s an essential step before bringing the stack up, especially if you haven’t run it before.
3.2 Configure Docker Compose for External Access
By default, crAPI binds services to 127.0.0.1, which works inside the containers but blocks access from your host machine (like ZAP or your browser). To make it reachable externally, you have two options:
Option 1: Modify the .env File
Edit the .env file and change:
LISTEN_IP=127.0.0.1to:
LISTEN_IP=0.0.0.0This tells Docker to bind services to all network interfaces, not just the loopback. If you’re not using the .env file, the inline LISTEN_IP method will override the default.
Option 2: Set the IP Inline with the Compose Command
Alternatively, you can override the variable directly in the command line:
LISTEN_IP="0.0.0.0" docker compose -f docker-compose.yml --compatibility up -d💡 I used this method to avoid changing the actual files in the repo — helpful for quick testing or scripting.
When I first tried restarting the stack with LISTEN_IP=0.0.0.0, I ran into issues — the services wouldn’t start cleanly. To fix it, I had to perform a full cleanup:
docker stop $(docker ps -q)
docker container prune -f
docker volume prune -f
docker-compose down -v --remove-orphans
docker-compose build --no-cache
docker-compose up -d3.3 Start crAPI
Once configured, launch the container stack:
docker-compose --compatibility up -dOr, if you’re using the inline method:
LISTEN_IP="0.0.0.0" docker compose -f docker-compose.yml --compatibility up -dVerify that the containers are running:
docker psYou should see services like crapi_frontend, crapi_identity, crapi_user, etc.

3.4 Access the Application
Once crAPI is running, open your browser and test the following URLs:
- Front-end UI:
http://localhost:8888
This is where you can register, log in, and explore the app. - Identity Service:
http://localhost:8888/identity
The backend for login, registration, and JWT generation. - Swagger/OpenAPI Spec (used for scanning):
http://localhost:8888/api/openapi.json
🧪 In most applications, the API spec is available at predictable paths like
/api/openapi.json,/swagger.json, or/v2/swagger.json. These files are based on the Swagger (now OpenAPI) standard, which was originally built to describe REST APIs in a machine-readable format.
However, in crAPI’s case, I couldn’t find the spec at any of the usual locations, nor was it documented in the repo. This means you may need to explore endpoints manually or use a proxy to map the API by traffic.

4. Reconnaissance and Mapping the API
With crAPI up and running, the next step is to understand the API surface area — what endpoints exist, which ones are protected, and how they respond to different requests. This stage is critical whether you’re testing an API for vulnerabilities or just trying to understand its behaviour.
4.1 What Is an API and Why Do We Scan It?
An API (Application Programming Interface) is a system of endpoints that allows different software components — like front-end apps and backend services — to communicate. Each endpoint typically exposes a function (like register, login, or fetch profile data), and may require authentication using credentials or Bearer tokens (e.g. JWTs).
We scan APIs to:
- Discover exposed endpoints
- Understand the request/response structure
- Identify broken or missing authentication
- Map out logical flow and access control
- Find vulnerabilities such as:
- Broken object-level authorization (BOLA)
- Excessive data exposure
- JWT handling issues
Learning to explore and map APIs is an essential skill for both defenders and attackers.
4.2 Passive Scanning with Browser DevTools
Before jumping into tools like ZAP or Burp, your browser alone can provide a surprising amount of visibility into how an API functions. Using the Network tab in your browser’s Developer Tools, you can observe how front-end apps interact with the back-end.
🔍 What to Look For
- Initial API requests made on page load (e.g.,
/login,/config.json) - JavaScript chunks loading dynamic content or front-end logic
- Endpoints, methods, and status codes
- Tokens or session identifiers in headers or responses
- Clear-text data (e.g., usernames, configuration)

Here you can see the browser requesting:
GET /login— the login form endpoint- Several JS files and assets
config.json— often contains useful metadata or even backend URLs
✅ Why This Matters
- It’s a fast, zero-effort recon method — no tools or scanning required.
- It helps you confirm if the app is live and if network traffic is behaving as expected.
- You can manually extract endpoints and replay them later in curl, Postman, or ZAP.
- It’s a great way to see where authentication is triggered and how client-side logic handles responses.
🧠 Passive scanning in the browser is especially useful when Swagger specs are unavailable. You can use it to build a quick picture of the API structure before moving on to proxy-based inspection.
🔍 Identify Technologies with Wappalyzer
To enhance this passive inspection, use a tool like Wappalyzer — a browser extension that automatically detects technologies used by a website or app. It can also be installed as a addon in OWASP ZAP (called Technology Detection) to analyze web traffic on the fly.
Wappalyzer can detect:
- Programming languages (e.g., Python)
- Web frameworks (e.g., Flask)
- JavaScript libraries (e.g., React, core-js)
- Web servers (e.g., NGINX)
- Operating systems
- Documentation and API tools (e.g., Swagger UI)

This insight helps you:
- Tailor your scanning strategy — e.g., target known Flask vulnerabilities
- Understand the architecture and API tooling used
- Confirm suspicions about backend tech without active probing
🧠 Combining DevTools and Wappalyzer gives you a strong foundation for manual API exploration. It sets the stage for deeper investigation with curl, Postman, or ZAP.
4.3 Looking for the Swagger/OpenAPI Spec
Most well-structured APIs today offer an OpenAPI specification (formerly known as Swagger), which documents all available endpoints, request parameters, response formats, and authentication methods.
In many applications, you’ll find the spec at predictable locations such as:
/api/openapi.json/swagger.json/v2/swagger.json
I looked for a spec file in crAPI at:
http://localhost:8888/api/openapi.jsonhttp://localhost:8888/swagger.json
But in my case, none of these paths worked, and the crAPI documentation doesn’t mention where the OpenAPI spec is located — if it even exists. I wasn’t able to find it in the code or through browsing either.
🕵️♂️ This is common in real-world assessments. Not every API has a published spec, and sometimes it’s outdated, broken, or hidden behind authentication. So it’s important to learn how to operate without one.
There are tools you can use to generate OpenAPI specification documents, that can be found at https://openapi.tools
4.4 Importing a Spec into OWASP ZAP (If Available)
If you do manage to find a valid OpenAPI/Swagger file, ZAP has a built-in importer that makes scanning much easier.
To import a spec into ZAP:
- Open ZAP and go to
Tools > Import > Import an OpenAPI definition. - Paste the URL or select a
.jsonfile from your machine. - ZAP will parse the spec and automatically generate a list of endpoints.
- These endpoints will appear in the Sites tree, ready for spidering or scanning.
⚠️ If the import fails, it’s usually due to schema errors or malformed JSON. You can validate the spec at https://editor.swagger.io.
Since crAPI didn’t expose a spec in my case, I had to fall back to manual exploration, which we’ll cover in the next section using ZAP’s proxy and manual browsing tools.
5. Scanning with ZAP
5.1 Manual Browsing via Proxy
To intercept traffic between your browser or CLI and crAPI, you need to route it through OWASP ZAP’s local proxy.
🛠️ Set Up the Proxy
By default, ZAP runs its proxy on:
- Address:
127.0.0.1 - Port:
8080
You can confirm or change this under:
Tools > Options > Local Proxies
(orZAP > Preferences > Local Proxieson macOS)
This is the endpoint ZAP listens on to intercept and inspect HTTP/HTTPS requests.
Option A: Use Your Browser
- Set your browser’s proxy settings to:
- HTTP Proxy:
127.0.0.1 - Port:
8080
- Navigate to
http://localhost:8888and interact with crAPI (register, log in, etc.) - ZAP will log each request and response under the Sites and History tabs.
Option B: Use curl from the CLI
Here’s a simple example:
curl -x http://127.0.0.1:8080 http://localhost:8888/api/garageThe -x flag in curl defines the proxy to use for the request. In this case, it sends traffic through ZAP’s proxy at 127.0.0.1:8080.
📖 For more details on the -x option and other curl flags, refer to the official curl manpage.
💡 Tip: If HTTPS requests fail due to certificate warnings, install ZAP’s root CA cert under
Tools > Options > Dynamic SSL Certificates
and import it into your browser’s certificate store.
5.2 Understanding and Extracting Bearer Tokens (JWT)
Many crAPI endpoints require authentication via Bearer tokens, which are implemented as JWTs (JSON Web Tokens).
To get a token:
- Register a user through the front-end or via a POST to
/identity/api/auth/register. - Log in using
/identity/api/auth/login, and note the returned token:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}You can include this token in your manual API requests like:
curl -x http://127.0.0.1:8080 \
-H "Authorization: Bearer eyJhbGciOi..." \
http://localhost:8888/user/api/profile🧠 Decode and inspect your JWT at https://jwt.io to understand the structure, claims, expiration time, and roles used in crAPI.
5.3 Active Scanning in ZAP
Once you’ve mapped a few endpoints — either by proxying requests through ZAP or importing a spec (if available) — you can begin active scanning. This allows ZAP to send crafted payloads to test for vulnerabilities in the API.
ZAP’s active scanner can find:
- Input validation issues (e.g., XSS, SQLi)
- Insecure HTTP headers
- Authentication and session handling flaws
- Authorization problems (e.g., accessing other users’ data)
- Endpoint misconfigurations
🛠️ How to Launch an Authenticated Active Scan
Because crAPI uses Bearer tokens (JWTs) to protect most endpoints, you need to make sure your Authorization header is included in the requests ZAP scans.
Here are two ways to do that:
✅ Option 1: Scan from an Existing Authenticated Request
This is the easiest and most reliable method.
- Use your browser, curl, or ZAP to send a request with the Bearer token, e.g.:
curl -x http://127.0.0.1:8080 \ -H "Authorization: Bearer eyJhbGciOi..." \ http://localhost:8888/user/api/profile - In ZAP, find the request in the History tab.
- Right-click it >
Attack > Active Scan. - This will launch a scan using the exact same headers, including your token.
🧠 This ensures ZAP replays the request with proper authentication.
✅ Option 2: Add the Bearer Token Globally with a Context
For broader scanning where ZAP automatically adds the token:
- In the Sites tab, right-click the target >
Include in Context > [New Context] - Go to
Tools > Options > Contexts > [Your Context] > HTTP Headers - Click Add and enter:
Header name: Authorization Header value: Bearer eyJhbGciOi... - Start your scan using this context. All requests will include the token automatically.
💡 Great for scanning multiple endpoints across a full API structure.

🧠 The “User” field here is only used for scripted or form-based login via ZAP Contexts. It is not used for Bearer tokens. Use one of the methods above to add your Authorization header.
ZAP will begin sending requests to all discovered endpoints, modifying inputs, altering headers, and fuzzing parameters to uncover potential vulnerabilities.
You can see the progress of the scan results and what it is doing by clicking the monitor icon:

🔍 Interpreting the Results
After the scan completes, findings will show up in the Alerts tab. Each alert includes:
- Risk level (Informational, Low, Medium, High)
- A description of the issue
- The affected URL and method
- Request/response samples
- Remediation advice
You can also see the bearer token in the request here:

⚠️ Important: If your JWT is missing or expired, many endpoints will return
401 Unauthorizedand ZAP won’t get meaningful results. Always ensure a valid token is included before launching the scan.💡 Advanced Tip: You can use ZAP Contexts and Script-based Authentication for more advanced automation — useful when tokens expire or multiple roles need testing.
Once you’ve completed a scan and reviewed the results, you’ll have a clear picture of what crAPI exposes — and how it behaves under attack. In the next section, we’ll summarize the key lessons from this setup and scanning workflow.
6. Summary of Key Learnings
Setting up and scanning OWASP crAPI with Docker Compose and OWASP ZAP provided a great end-to-end look at how modern APIs behave — and how to start testing them like a security professional.
Here’s a recap of the most important takeaways:
🚀 Deployment Tips
- Always use
git cloneinstead of downloading ZIPs from GitHub, especially for tagged releases — avoids file extraction and encoding issues. - Run crAPI in a virtual machine to isolate your lab environment and keep your host clean.
- Set
LISTEN_IP=0.0.0.0to expose services to your host tools — either in the.envfile or inline withdocker compose.
🔍 API Mapping Techniques
- Look for OpenAPI specs at common paths like
/api/openapi.json,/swagger.json, or/v2/swagger.json. - In crAPI, no spec was available — this is common in the real world. Learn to map endpoints manually.
- Proxying your browser or CLI (e.g.,
curl -x) through ZAP is a reliable method for discovering undocumented endpoints.
🔐 Authentication and JWT Handling
- crAPI uses JWT Bearer tokens, which are issued after login.
- You can extract these tokens from login responses and replay them using curl or through ZAP headers.
- Use tools like jwt.io to decode and inspect tokens — this helps understand what roles or claims are being passed around.
🛡️ Scanning Strategy with ZAP
- Use manual exploration to populate the ZAP Sites tree before launching active scans.
- Add Bearer tokens manually in the Headers tab to avoid
401 Unauthorizedresponses. - Review scan findings in the Alerts tab to identify insecure endpoints, misconfigured headers, or common web vulnerabilities.
By working through this flow, you’ve practiced deploying a broken API, analyzing its architecture, and scanning it using open-source tools — all without needing expensive licenses or enterprise platforms.
7. Next Steps
Once you’ve successfully set up crAPI, intercepted traffic, and run your first active scans with ZAP, there’s a lot more you can explore. This lab is just the beginning of your journey into API security testing and secure architecture design.
Here are some natural next steps:
🔁 Automate Authenticated Scans
Instead of manually pasting JWTs into ZAP each time, you can:
- Use ZAP Contexts to define login flows
- Create a Script-based Authentication Handler to programmatically fetch and refresh tokens
- Set up forced user mode to simulate different roles or user IDs
This brings you closer to real-world pen testing workflows.
🧪 Attack crAPI with Known Vulnerabilities
OWASP crAPI is full of intentionally insecure endpoints. Try attacking it using:
- OWASP ZAP Fuzzer to brute-force IDs or tokens
- SQLi and XSS payloads from SecLists
- Manual testing tools like Postman or Insomnia to replay and manipulate requests
Track your findings and build a checklist of broken controls.
🔄 Compare with Other Tools
ZAP is powerful, but you may also want to:
- Try scanning crAPI with Burp Suite Community Edition
- Use Postman’s API testing features to test requests and extract tokens dynamically
- Use Kiterunner, ffuf, or ParamSpider for endpoint fuzzing and wordlist discovery
Each tool provides different insights and scanning depth.
🛡️ Integrate WAFs or API Gateways
Want to go beyond scanning? Set up a Web Application Firewall (WAF) or API Gateway in front of crAPI and:
- Write custom rules to block specific request patterns
- Log and monitor attacks via a reverse proxy
- Test whether your WAF correctly blocks known exploits
Tools to try include:
- FortiADC / FortiWeb (for policy-based protection)
- Kong Gateway or NGINX (for open-source control)
- F5 ASM / Advanced WAF if you have access
🧱 Bonus: This setup mimics enterprise security layers and is great for learning how WAFs handle real traffic.
These steps help transition you from beginner exploration into real-world API security testing and defensive engineering. Whether you’re building, breaking, or protecting APIs — crAPI is the perfect training ground.
8. Resources & Further Reading
To continue your learning and build on what you’ve done with OWASP crAPI and ZAP, here are the most relevant tools, documentation, and community resources:
🔧 Official Tools & Documentation
- OWASP crAPI GitHub Repository
https://github.com/OWASP/crAPI
The source of the intentionally vulnerable API project used in this guide. - OWASP ZAP (Zed Attack Proxy)
https://www.zaproxy.org/
Official site for downloads, documentation, add-ons, and user guides. - ZAP OpenAPI Add-on
https://www.zaproxy.org/docs/desktop/addons/openapi-support/
Add-on for importing Swagger/OpenAPI specs into ZAP for easier scanning. - JWT Debugging Tool
https://jwt.io/
Decode, inspect, and learn about JWT structure and usage. - curl Manual
https://curl.se/docs/manpage.html
Learn more about using-xfor proxying,-Hfor custom headers, and other useful flags.
📚 API Security Learning
- OWASP API Security Top 10
https://owasp.org/www-project-api-security/
The most critical API security risks every engineer and tester should know. - SecLists – Payloads & Wordlists
https://github.com/danielmiessler/SecLists
A treasure trove of input fuzzing payloads, API endpoint wordlists, and more. - PortSwigger’s Web Security Academy (API Section)
https://portswigger.net/web-security/api
Free, interactive labs to practice attacking and defending APIs.
🧰 Optional Tools for Next-Level Testing
- Postman – https://www.postman.com/
- Insomnia – https://insomnia.rest/
- Burp Suite (Community Edition) – https://portswigger.net/burp
- Kiterunner – https://github.com/assetnote/kiterunner
- ffuf (Fast web fuzzer) – https://github.com/ffuf/ffuf
🔁 Bookmark this list and refer back to it as your skills grow. These tools and references form the foundation of most real-world API testing workflows.

