# 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](https://github.com/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)](https://owasp.org/) 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](https://www.zaproxy.org/)** – 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](https://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. ![[Pasted image 20250620233655.png]] # 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-compose ``` Alternatively, refer to the [official Docker installation guide](https://docs.docker.com/get-docker/) and [Docker Compose setup](https://docs.docker.com/compose/install/). - **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/](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](https://docs.docker.com/get-started/) and the [ZAP User Manual](https://www.zaproxy.org/docs/desktop/start/) 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](https://github.com/OWASP/crAPI/archive/refs/tags/v1.1.5.zip), because that’s what was linked on the [crAPI develop branch page](https://github.com/OWASP/crAPI/tree/develop). 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 clone` the 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 ``` ![[Pasted image 20250620235232.png]] 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.1 ``` to: ``` LISTEN_IP=0.0.0.0 ``` This 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 -d ``` --- ## 3.3 Start crAPI Once configured, launch the container stack: ``` docker-compose --compatibility up -d ``` Or, if you’re using the inline method: ``` LISTEN_IP="0.0.0.0" docker compose -f docker-compose.yml --compatibility up -d ``` Verify that the containers are running: ``` docker ps ``` You should see services like `crapi_frontend`, `crapi_identity`, `crapi_user`, etc. ![[Pasted image 20250620235252.png]] --- ## 3.4 Access the Application Once crAPI is running, open your browser and test the following URLs: - **Front-end UI:** [http://localhost:8888](http://localhost:8888/) This is where you can register, log in, and explore the app. - **Identity Service:** [http://localhost:8888/identity](http://localhost:8888/identity) The backend for login, registration, and JWT generation. - **Swagger/OpenAPI Spec (used for scanning):** [http://localhost:8888/api/openapi.json](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. ![[Pasted image 20250620235308.png]] --- # 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) ![[Pasted image 20250620235352.png]] 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](https://www.wappalyzer.com/)** — 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) ![[Pasted image 20250620235433.png]] 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.json](http://localhost:8888/api/openapi.json) - [http://localhost:8888/swagger.json](http://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](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: 1. Open ZAP and go to `Tools > Import > Import an OpenAPI definition`. 2. Paste the URL or select a `.json` file from your machine. 3. ZAP will parse the spec and automatically generate a list of endpoints. 4. 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](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` > (or `ZAP > Preferences > Local Proxies` on macOS) This is the endpoint ZAP listens on to intercept and inspect HTTP/HTTPS requests. #### Option A: Use Your Browser 1. Set your browser’s proxy settings to: - **HTTP Proxy:** `127.0.0.1` - **Port:** `8080` 1. Navigate to [http://localhost:8888](http://localhost:8888/) and interact with crAPI (register, log in, etc.) 2. 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/garage ``` The `-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](https://curl.se/docs/manpage.html). > 💡 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: 1. Register a user through the front-end or via a POST to `/identity/api/auth/register`. 2. 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](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. 1. 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` 2. In ZAP, find the request in the **History** tab. 3. Right-click it > `Attack > Active Scan`. 4. 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: 1. In the **Sites** tab, right-click the target > `Include in Context > [New Context]` 2. Go to `Tools > Options > Contexts > [Your Context] > HTTP Headers` 3. Click **Add** and enter: `Header name: Authorization Header value: Bearer eyJhbGciOi...` 4. Start your scan using this context. All requests will include the token automatically. > 💡 Great for scanning multiple endpoints across a full API structure. ![[Pasted image 20250620235507.png]] > 🧠 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: ![[Pasted image 20250620235644.png]] ### 🔍 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: ![[Pasted image 20250620235702.png]] > ⚠️ **Important:** If your JWT is missing or expired, many endpoints will return `401 Unauthorized` and 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 clone`** instead 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.0` to expose services to your host tools — either in the `.env` file or inline with `docker 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](https://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 Unauthorized` responses. - 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](https://github.com/danielmiessler/SecLists) - Manual testing tools like [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/) 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](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/](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/](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/](https://jwt.io/) Decode, inspect, and learn about JWT structure and usage. - **curl Manual** [https://curl.se/docs/manpage.html](https://curl.se/docs/manpage.html) Learn more about using `-x` for proxying, `-H` for custom headers, and other useful flags. ## 📚 API Security Learning - **OWASP API Security Top 10** [https://owasp.org/www-project-api-security/](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](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](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/](https://www.postman.com/) - **Insomnia** – [https://insomnia.rest/](https://insomnia.rest/) - **Burp Suite (Community Edition)** – [https://portswigger.net/burp](https://portswigger.net/burp) - **Kiterunner** – [https://github.com/assetnote/kiterunner](https://github.com/assetnote/kiterunner) - **ffuf (Fast web fuzzer)** – [https://github.com/ffuf/ffuf](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.