An exchange can have a polished trading screen and still get the important things wrong: who can move funds, when a deposit becomes spendable, or whether two withdrawal requests can spend the same balance. Understanding those failures takes more than recognizing a familiar vulnerability name. You need an application where the consequences play out.
Today, we're introducing Bitvulnex, a deliberately vulnerable Bitcoin exchange built by Blaze Information Security. It contains 40 planted vulnerabilities across web security, exchange business logic, Bitcoin-related workflows, and infrastructure. You can run it yourself, explore its code, and use it for training.
The idea is similar to OWASP Juice Shop, applied to a cryptocurrency exchange: a working application that gives people somewhere to investigate security mistakes and understand what they enable. Its origins, however, were in a different kind of testing.
From harness evaluation to a public training lab
The project started as a target for evaluating our own agentic pentest harness. We needed an application with connected workflows and intentional flaws that we could return to between runs.
A target like this gives us a concrete basis for asking whether a harness can discover an attack surface, investigate a weakness, and validate its impact. An authorization error should lead to evidence of unauthorized access. A withdrawal race should lead to evidence of an accounting failure. A report should explain how the outcome happened and what conditions it required.
Bitvulnex then expanded into a training environment. The same workflows that made it useful for harness evaluation gave people room to practice: register an account, explore the exchange, form a hypothesis, test it, and explain the result. Later, we also used it for recruitment exercises.
Those uses share a useful property. A realistic target gives someone room to show how they investigate, rather than only whether they know a particular payload. It also creates opportunities to assess how clearly they distinguish a suspected issue from a demonstrated vulnerability.
We decided to make Bitvulnex available to the community because that environment could be useful well beyond our internal work. Security teams, educators, researchers, and independent learners can now run it and adapt it to their own exercises.
An exchange you can actually explore
Bitvulnex includes registration, KYC, deposits, spot trading, margin trading, lending and staking, OTC, P2P, withdrawals, treasury operations, administration, and a support desk. The trading interface includes an order book, candlestick chart, recent trades, and several order types.

The trading screen combines market activity and order entry. This screenshot shows the guest view; placing orders requires signing in. Prices and funds are simulated.
The breadth matters because exchange security depends on interactions between features. Identity checks influence who can use a workflow. KYC tiers affect permissions and limits. Trading activity influences prices. Background jobs act on balances, transactions, and positions.
A flaw in one part of that system can become more interesting when another part relies on its output. A price that appears on a public screen, for example, may also be consumed by a liquidation worker. Investigating that relationship teaches something different from finding an isolated input-validation bug.
The intentional flaws are embedded in plausible business code. They are not marked with comments telling the learner where to look. The repository includes an instructor-oriented vulnerability ledger, but you can leave that aside and approach the application as a black-box target first.
What exchange vulnerabilities look like in practice
The lab covers familiar web security problems, including access-control failures, injection, cross-site scripting, and server-side request forgery. It also includes mistakes that require understanding the exchange's rules.
Balances, transactions, and concurrency
Consider a withdrawal workflow that checks a user's balance and then debits it in a separate operation. Each request can look reasonable on its own. If concurrent requests pass the check before either completes the debit, the workflow can spend more than the intended balance permits.
Bitvulnex includes that kind of withdrawal race, along with other financial logic flaws such as concurrent staking reward claims and internal transfers that bypass limits. These exercises encourage learners to identify the invariant a workflow should preserve, then test whether it survives concurrent requests or an alternate path through the application.
The useful question is concrete: can the user obtain a financial outcome the exchange should prevent, and can you prove the resulting state change?
Trading activity and downstream decisions
Bitvulnex includes self-trading and price-oracle manipulation scenarios. The learning opportunity is to follow a price through the system: how it changes, where it is cached, and which jobs trust it when making decisions about positions.

The markets view gives learners an entry point for observing prices and activity before investigating how the application uses that state.
The repository's recorded oracle scenario demonstrates manipulated pricing leading to forced liquidation of a margin position. That illustrates why a technical report needs to name the actual outcome precisely. A manipulated price, a liquidation, and account takeover are different claims, each requiring its own evidence.
Deposits and Bitcoin-related assumptions
Other exercises involve crediting deposits before confirmation, handling refunds around replacement transactions, and disagreement between how a transaction-signing workflow validates a partially signed Bitcoin transaction (PSBT) and what it later broadcasts.
These are opportunities to examine the boundary between application accounting and the behavior the application expects from Bitcoin infrastructure. The lab uses a JavaScript Bitcoin RPC mock with regtest-style simulated behavior. It does not connect to mainnet or require real funds, keys, or blockchain infrastructure.
Customer input reaching internal systems
KYC, support, and compliance workflows create additional trust boundaries. Bitvulnex includes document-handling errors, customer input rendered in staff interfaces, and a KYC URL-import feature that can reach internal mock services through SSRF.
The supplied metadata and S3 mocks let learners explore a cloud-shaped attack path using synthetic credentials and documents. This gives the exercise a meaningful consequence without depending on a real cloud account.
How the lab is put together
The application uses Next.js 15, React 19, TypeScript, and Tailwind. PostgreSQL and Prisma hold its state. Redis and BullMQ support background jobs, including deposit handling, withdrawals, liquidations, and simulated market activity. A WebSocket gateway supplies live trading updates, and nginx sits in front of the web tier.
Docker Compose brings these pieces together with the Bitcoin RPC mock, mock cloud metadata service, mock S3 service, and a one-shot migration container that initializes the database and seeds synthetic users.
Background activity is part of the learning environment. It gives the exchange behavior between requests, so learners can investigate timing, stale state, and the effect of one workflow on another. For quieter exercises, the ambient activity simulator can be disabled through configuration.
The repository also documents four larger attack scenarios involving simulated wallet loss, administrative control and persistence, price-oracle abuse, and user/KYC data exposure. They give learners a reason to connect individual findings and demonstrate a larger outcome.
Install Bitvulnex locally
You need Git and Docker with Compose v2. Docker Desktop is the documented route on Windows and macOS; Docker Engine works on Linux. On Windows, use Docker Desktop's WSL2 backend.
Run Bitvulnex in a disposable VM or isolated lab environment. It is intentionally exploitable. Keep it off the public internet and use only synthetic data and the supplied mocks. The default Compose port mapping can listen beyond localhost, so opening it at a localhost URL does not itself restrict who can reach the service.
Clone the repository and create the configuration file:
git clone https://github.com/blazeinfosec/bitvulnex.git
cd bitvulnex
cp .env.example .env
If you use native PowerShell, replace the final command with Copy-Item .env.example .env.
Open .env and set CTF_SALT to your own value of at least eight characters. For an individual learning session, set WEB_API_REPLICAS=1. The shipped default has five API replicas and is tuned for concurrent testing; reducing the replica count lowers memory use. Leave enough headroom for the web processes and supporting services. If port 80 is already occupied, set WEB_PORT=8080.
Start the stack:
docker compose up -d --build
The first build takes a few minutes. The migration container applies migrations, seeds the database, and exits. Check its status and the health endpoint:
docker compose ps -a
curl http://localhost/api/health
The db-migrate container should show Exited (0), and the health endpoint should return a JSON response with status set to ok. If you configured port 8080, use http://localhost:8080/api/health instead.
Open http://localhost/, create an ordinary customer account at /signup, and start exploring. Public API documentation is available at /docs. Use the corresponding port in browser URLs if you changed WEB_PORT.

The landing page identifies Bitvulnex as a training application and points learners toward accounts, markets, and API documentation.
To stop the environment while keeping its data:
docker compose down
To delete the lab's volumes and start again with a fresh seeded environment:
docker compose down -v
docker compose up -d --build
The README covers configuration, troubleshooting, and instructor scripts. Host-side tests and instructor scripts require Node 22 and pnpm 9; they are not prerequisites for the basic Docker startup.
Learn independently or run a workshop
For an independent exercise, start with an ordinary account and map the customer workflows. Pick a boundary to investigate: ownership of an order, authorization for an operation, a balance change, or a customer's input reaching a staff tool.
Write down your hypothesis before testing. Afterward, record the prerequisites, the request or action that triggered the issue, the resulting state change, and the control that should have prevented it. Propose a fix that addresses the root cause.
Bitvulnex also has an optional CTF mode with 40 vulnerability targets and four chain bonus targets. It supports flag submissions, hints, and scoring, with a learner page at /ctf and instructor controls at /admin/ctf. The README explains the toggles and cohort setup.
Instructors can use the vulnerability ledger and supporting materials to plan exercises and debrief results. Those documents contain spoilers: VULNS.md, the instructor manual, exploitation receipts, and hint files disclose answers. Learners who want a discovery exercise should avoid them until afterward.
A flag is useful for tracking progress, but a technical assessment should also require evidence of the claimed outcome. The lab uses different flag delivery mechanisms, including proof-shape validation and discovery of static secrets. A submission alone does not always establish that an entire attack path was executed.
Using Bitvulnex to evaluate pentest agents
Bitvulnex remains useful for the purpose that started the project: evaluating a pentest harness against a known, resettable target. Its documented flaws let an evaluator compare findings with an expected set and investigate missed coverage or unsupported reports.
Useful evaluation questions include whether the harness discovers relevant workflows, respects attack prerequisites, proves exploitation, connects dependent weaknesses, and produces evidence another tester can verify. Those questions also help separate finding a suspicious pattern from completing a pentest task.
Any published benchmark should make its conditions clear: the repository revision, configuration, starting access, whether source code was available, and whether the evaluator exposed the answer key. Those choices materially change the exercise.
Because Bitvulnex is public, its code and solutions may also enter model training data. Results on this lab are useful evidence about performance under stated conditions. They should be interpreted alongside evaluations on other targets.
For recruitment, the same environment creates room to discuss investigation, business logic, validation, impact, and remediation. How someone explains a finding can be as informative as the finding itself.
Get Bitvulnex and make it your own
Bitvulnex is available under the MIT license. You can run it, fork it, adapt exercises, and use it in your own isolated training environment. The repository includes contribution guidelines and an issue tracker.
If a flaw is documented in the vulnerability ledger, it is an intentional part of the lab. If you discover an unintended bug, open an issue so we can investigate it.
We built Bitvulnex to give ourselves a useful target. We're sharing it so others can learn from the same workflows, test their ideas, and improve the environment with us.



