Self-hosted service
erev0s/VAmPI avatar
erev0s/VAmPI

erev0s/VAmPI: A Flask API for OWASP API Vulnerability Testing

Vulnerable REST API with OWASP top 10 vulnerabilities for security testing

1,339 stars609 forksPythonMIT

At a glance

What is it?
erev0s/VAmPI is a deliberately vulnerable Flask REST API for security testing, API security learning, and tool evaluation. It combines OpenAPI 3, Swagger UI, token authentication, Docker support, and a switch between vulnerable and less vulnerable configurations.
Who is it for?
Adopt erev0s/VAmPI when you need a controlled API fixture for learning, teaching, or evaluating security tools, provided the environment is isolated. Do not deploy it as a trusted service or expose it to untrusted traffic.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

VAmPI's API Security Testing Fixture

erev0s/VAmPI is built for people who need a target with known weaknesses rather than a production API. The README describes it as a vulnerable REST API made with Flask and based on the OWASP Top 10 vulnerabilities for APIs. Its stated users include security tool authors, instructors, learners, and developers who want to evaluate whether an API security tool identifies particular failure modes. It is not a general-purpose business application and should not be treated as a safe deployment of user data or authentication code.

The application models a small book service around dummy users. An unregistered visitor can see limited information about the users included in the API. After registering and logging in, the user receives a token and can post a book. A book contains a title and a secret, with each book associated with an individual user. The documented authorization rule is that only the owner should be able to view a book's secret. This gives security testers concrete object-level authorization cases rather than a collection of disconnected endpoints.

The project is useful when a scanner needs a known target with controllable vulnerable and non-vulnerable states. That control matters when a tester is investigating false positives or false negatives. It can also support classroom exercises because the API has a visible user, authentication, and book-object flow. The repository is not archived, but its last push was on 2026-04-07, and no GitHub releases are listed. The documented upgrade surface is therefore the repository itself rather than a release-based package line.

Flask Routes, Data, and Token Boundaries

The repository layout shows a Flask application in `app.py`, configuration in `config.py`, API views under `api_views/`, database code under `database/`, and models under `models/`. The requirements include Flask, Flask-SQLAlchemy, SQLAlchemy, Connexion, JSON Schema, PyJWT, Swagger UI, and MarkupSafe. Based on the README's endpoint table, the data flow covers database creation, user registration, login, profile access, user administration, and book creation and retrieval.

The first important operational path is `/createdb`. The README's FAQ says a database error can occur when endpoints are reached before this path is used. The endpoint creates and populates the database with dummy data, which makes it a required initialization step for the documented exercise flow. After that, a user can register at `/users/v1/register`, log in at `/users/v1/login`, and use the returned token to access authenticated operations such as `/me` and `POST /books/v1`. Book retrieval at `/books/v1/{book}` includes the secret associated with the book, creating a direct test target for broken object-level authorization.

Authentication is token based. The README says the token lifetime can be adjusted from `app.py` or through container environment variables. It also identifies JWT authentication bypass through a weak signing key as one of the vulnerabilities, so token presence should not be interpreted by a tester as proof that authorization is correct. The API also contains a `/users/v1/_debug` endpoint for displaying detailed user information, an explicit excessive-data-exposure case. The architecture is small enough to inspect, but the endpoints still represent the common boundary where identity, object access, and input handling meet.

The VAmPI Vulnerability Catalog and Intended Scope

The README lists SQL injection, unauthorized password change, broken object-level authorization, mass assignment, excessive data exposure through the debug endpoint, user and password enumeration, RegexDOS denial of service, lack of resource and rate limiting, and JWT authentication bypass through a weak signing key. This is a deliberately broad catalog, but it should not be read as a complete API security taxonomy or as a guarantee that every listed weakness is reachable in every configuration.

The global vulnerability switch is the central experimental control. In a normal Python run, the README instructs users to edit the `alive` and `vuln` variables in `app.py`. `alive` is measured in seconds and controls token expiration. `vuln` behaves like a boolean, with `1` enabling the vulnerable environment and `0` disabling it. Docker accepts the corresponding environment variables, `vulnerable` and `tokentimetolive`. The secure and vulnerable configurations can therefore be started as separate containers on different host ports, allowing a tester to compare behavior while keeping the target definition explicit.

This design is different from trying to assess a real service that silently combines several weaknesses. VAmPI gives a security tool author a controlled comparison between configurations. It is also different from using only an OpenAPI editor or Postman collection. Those artifacts describe or exercise endpoints, while VAmPI implements the endpoint behavior that can be evaluated. The README includes OpenAPI 3 specifications and a Postman Collection, so clients can be used for inspection and manual interaction, but neither artifact replaces the running application.

Running VAmPI Locally and Reaching Swagger UI

The documented local installation installs the pinned Python requirements and starts `app.py`. Run these commands from the repository directory in an isolated test environment. The first command installs `requirements.txt`; the second starts the Flask application. After the application starts, request `/createdb` before using endpoints that depend on the dummy database, then open the Swagger UI at the documented local path.

bash
pip3 install -r requirements.txt
python3 app.py

The README documents `http://127.0.0.1:5000/ui/` as the Swagger UI location. Swagger UI provides direct interaction with the API and is the clearest first use for seeing the registration, login, and book operations. The Swagger UI is documentation and an interaction client, not a security test result. A tester still needs to inspect authorization boundaries and input handling rather than judging the target merely from successful requests.

Docker is the alternative installation path when the tester wants a repeatable runtime. The README gives a one-container command that publishes host port 5000 to container port 5000:

bash
docker run -p 5000:5000 erev0s/vampi:latest

The README warns that newer macOS versions may use host port 5001 instead because of a possible AirPlay Receiver conflict:

The Compose file defines two services. `vampi-secure` maps host port 5001 to container port 5000 and sets `vulnerable=0`; `vampi-vulnerable` maps host port 5002 to container port 5000 and sets `vulnerable=1`. Both use `tokentimetolive=3600`. This is the clearest built-in alternative to running a single vulnerable service: compare the two documented states without editing the source.

Docker Compose Configuration for Controlled Comparisons

Docker Compose is the more useful path when the purpose is side-by-side evaluation. The checked-in `docker-compose.yaml` builds from the current repository and creates two named containers, `vampi-secure` and `vampi-vulnerable`. The secure instance is available on host port 5001, while the vulnerable instance is available on host port 5002.

Start both services with the command documented in the README:

bash
docker-compose up -d

The distinction is configured through environment variables rather than by maintaining separate application code. The secure service uses `vulnerable=0`, and the vulnerable service uses `vulnerable=1`. Both use `tokentimetolive=3600`, which keeps token lifetime consistent for the comparison. That consistency matters when evaluating authentication or authorization behavior, although the README does not claim that equal token lifetime eliminates every source of test variation.

The Docker configuration also uses `build: ./`, so Compose builds the local checkout rather than downloading a source archive through a command documented here. This has a practical consequence: changing the repository's `Dockerfile`, requirements, or application files can change the image used by Compose. The Dockerfile is based on `python:3.11-alpine`, installs `requirements.txt` in a builder stage, copies the application into `/vampi`, and starts it with `python app.py`. It sets `vulnerable=1` and `tokentimetolive=60` as image defaults, while Compose overrides those values for its two services. The README also gives a direct Docker command for explicitly passing the variables.

bash
docker run -d -e vulnerable=0 -e tokentimetolive=300 -p 5000:5000 erev0s/vampi:latest

This command creates a less vulnerable instance with a 300-second token lifetime. The README says a second container can be started with `vulnerable=1` on another port. The distinction is useful for controlled testing, but it does not make the application suitable for an exposed environment.

OpenAPI 3 and Manual API Exploration

VAmPI is based on OpenAPI 3, and the repository includes an `openapi_specs` directory. The README says the specification can be supplied to the Swagger Editor, while a running VAmPI instance provides Swagger UI at `/ui/`. The specification and the runtime are complementary: the specification describes the intended request surface, and the running service demonstrates whether authentication, authorization, and input handling behave as expected.

The first useful manual sequence follows the documented action flow. Start the application, request `/createdb`, register through `/users/v1/register`, and log in through `/users/v1/login`. The login response provides the token required for authenticated actions. A tester can then inspect `/me`, post a book through `POST /books/v1`, and retrieve a book through `GET /books/v1/{book}`. This sequence makes it possible to examine whether data visible to one account can affect or expose another account's book.

The README also lists user-management and diagnostic routes, including `/users/v1`, `/users/v1/_debug`, `DELETE /users/v1/{username}`, and the email and password update routes. Their presence does not by itself confirm that each vulnerability is enabled. The `vuln` setting and the relevant request behavior determine the scenario. OpenAPI tooling is therefore best treated as a map of attack surface, not as an authorization oracle.

For API security testing, VAmPI's alternative to a full application assessment is not another API client. It is the secure Compose configuration paired with the vulnerable configuration. That comparison keeps most of the route and data model structure constant while changing the documented vulnerability switch. It is a more controlled approach than evaluating unrelated sample applications, although the repository does not document a formal scoring system or a pass criterion for a scanner.

Operational Limits of a Vulnerable API Fixture

The main limitation is the one implied by the project's purpose: VAmPI is intentionally unsafe. The README's vulnerability list includes denial-of-service conditions, weak JWT signing, excessive data exposure, unauthorized password changes, and object authorization failures. Running the service on a shared host, a public network, or a network containing sensitive data would expose other systems and users to the very behavior the fixture is meant to demonstrate. Isolation is therefore a prerequisite, although the README does not provide a dedicated deployment-hardening guide.

Another limitation is that the API is small. The book workflow, dummy users, and listed routes make it convenient for demonstrations, but they do not represent every architecture an API scanner will encounter. There is no documented production data model, distributed deployment design, or formal test corpus beyond the listed vulnerabilities and included specifications. A tool that passes against VAmPI has not thereby been validated against an unrelated production service.

The project also has no GitHub releases. The README documents local execution and Docker images, but it does not publish a compatibility matrix for future Python, Flask, or dependency changes. The requirements file pins several packages, including `connexion[swagger-ui]==2.14.2`, `flask==2.2.2`, `sqlalchemy==2.0.2`, and `PyJWT==2.6.0`. Anyone changing those versions should treat the result as a new test environment rather than assume that behavior remains identical. Upgrade work is mainly dependency review, image rebuild, and rerunning the scenarios, with the repository's last push recorded on 2026-04-07.

The MIT license permits use and modification under its terms, but VAmPI's purpose still requires operational care. The license does not convert a vulnerable fixture into a production service, and users remain responsible for where they run it and what data they place around it.

Choosing the Right VAmPI Scenario

VAmPI fits an API security learning session, a classroom demonstration, or a controlled evaluation of detection tools. Its strongest feature is the documented ability to turn vulnerability behavior on or off while retaining the same general API workflow. That makes it easier to distinguish a tool finding caused by the intended vulnerable configuration from one seen in the disabled configuration.

It is a poor fit for a production deployment, a public demo without network controls, or a claim that a scanner has been broadly validated. It is also a poor choice when the real goal is to test a specific production integration, since the repository documents dummy data and a deliberately constructed vulnerability catalog rather than a representative business system.

Before using it, verify the exact source and configuration being run. For local execution, inspect `alive` and `vuln` in `app.py`. For Docker execution, inspect `vulnerable` and `tokentimetolive`, and confirm whether Compose is using the secure service on port 5001 or the vulnerable service on port 5002. Then call `/createdb` and confirm that database-dependent endpoints respond. Those checks establish the intended VAmPI scenario before interpreting any security-tool result.

Editorial conclusion

Adopt erev0s/VAmPI when you need a controlled API fixture for learning, teaching, or evaluating security tools, provided the environment is isolated. Do not deploy it as a trusted service or expose it to untrusted traffic. Verify first that the application is bound only to an appropriate test network, that `/createdb` has initialized the database, and that the `vuln` or `vulnerable` setting matches the scenario being studied. The repository's last push was on 2026-04-07, and it has no GitHub releases, so treat version changes as repository changes rather than released artifacts.

Frequently asked questions

How do I install and run erev0s/VAmPI?

The README documents installing `requirements.txt` with `pip3 install -r requirements.txt`, then starting the Flask application with `python3 app.py`. It also documents Docker and Docker Compose as alternatives.

Why do erev0s/VAmPI endpoints return a database error?

The README FAQ says to issue a request to `/createdb` to populate the database before reaching other endpoints. This is the documented initialization step.

Can I switch erev0s/VAmPI between vulnerable and non-vulnerable modes?

Yes. The README says to edit `vuln` in `app.py` for a normal run, or use the `vulnerable` environment variable with Docker. It describes `vuln=1` and `vulnerable=1` as vulnerable settings, and `vuln=0` and `vulnerable=0` as the disabled-vulnerability setting.

Official sources

  1. erev0s/VAmPI on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/erev0s-vampi.svg)](https://hysenlabs.com/projects/erev0s-vampi)

Was this useful?