A deliberately vulnerable banking application designed for practicing Security Testing of Web App, APIs, AI integrated App and secure code reviews. Features common vulnerabilities found in real-world applications, making it an ideal platform for security professionals, developers, and enthusiasts to learn pentesting and secure coding practices.
Vulnerable Bank Application π¦
A deliberately vulnerable web application for practicing application security testing of Web, APIs and LLMs, secure code review and implementing security in CI/CD pipelines.
β οΈ WARNING: This application is intentionally vulnerable and should only be used for educational purposes in isolated environments.
Overview
This project is a simple banking application with multiple security vulnerabilities built in. It's designed to help security engineers, developers, interns, QA analyst and DevSecOps practitioners learn about:
- Common web application and API vulnerabilities
- AI/LLM Vulnerabilities
- Secure coding practices
- Security testing automation
- DevSecOps implementation
Features & Vulnerabilities
Core Banking Features
- π User Authentication & Authorization
- π° Account Balance Management
- πΈ Money Transfers
- π Loan Requests
- π€ Profile Picture Upload
- π Transaction History
- π Transaction Analytics Dashboard (GraphQL-backed)
- π Password Reset System (3-digit PIN)
- π³ Multi-Currency Virtual Cards Management
- π± Virtual Card Funding from Main USD Balance with built-in currency conversion (
USD,GBP,NGN,JPY,EUR,QAR,BTC,ETH) - π Public Merchant Payment API for intentionally vulnerable ecommerce/demo integrations
- π± Bill Payments System
- π€ AI Customer Support Agent (Real LLM with DeepSeek API / Mock Mode)
Implemented Vulnerabilities
- Authentication & Authorization
- Data Security
- Transaction Vulnerabilities
- File Operations
- Session Management
- Client and Server-Side Flaws
- Virtual Card Vulnerabilities
- Bill Payment Vulnerabilities
- Merchant Payment API Vulnerabilities
- AI Customer Support Vulnerabilities
- GraphQL Vulnerabilities
/graphql
- SQL injection in GraphQL resolver query construction
- Missing GraphQL depth / complexity controls
- Raw GraphQL error disclosure
- Transaction analytics exposure through admin-scoped queries
Installation & Setup π
Prerequisites
- Docker and Docker Compose (for containerized setup)
- PostgreSQL (if running locally)
- Python 3.9 or higher (for local setup)
- Git
Option 1: Using Docker (Recommended)
Using Docker Compose (Easiest)
- Clone the repository:
git clone https://github.com/Commando-X/vuln-bank.git
cd vuln-bank
- Start the application:
docker-compose up -d --build
The application will be available at http://localhost:5000
Container recovery behavior
The Docker setup includes a few operational safeguards so the app can recover without manual SSH intervention:webanddbuserestart: unless-stopped, so Docker restarts them automatically if the process exits.dbexposes a health check, andwebwaits for Postgres readiness before starting.webruns the Flask development server withdebug=True(intentional β preserves the training scenarios that target the Werkzeug debugger).webexposesGET /healthzso the container can report whether the app and database are actually usable.
Local smoke test
You can validate the local runtime wiring without starting real containers:python3 -m unittest discover -s tests -v
This checks the /healthz endpoint behavior and verifies that start.sh waits for the database and then launches the Flask app. If the Flask app dependencies are not installed in your current Python environment, the /healthz route test is skipped and the startup-script smoke test still runs.
Using Docker Only
- Clone the repository:
git clone https://github.com/Commando-X/vuln-bank.git
cd vuln-bank
- Build the Docker image:
docker build -t vuln-bank .
- Run the container:
docker run -p 5000:5000 vuln-bank
Option 2: Local Installation
Prerequisites
- Python 3.9 or higher
- PostgreSQL installed and running
- pip (Python package manager)
- Git
Steps
- Clone the repository:
git clone https://github.com/Commando-X/vuln-bank.git
cd vuln-bank
- Create and activate a virtual environment (recommended):
# On Windows
python -m venv venv
venv\Scripts\activate
On Linux/Mac
python3 -m venv venv
source venv/bin/activate
- Install required packages:
pip install -r requirements.txt
- Create necessary directories:
# On Windows
mkdir static\uploads
On Linux/Mac
mkdir -p static/uploads
- Modify the .env file:
- Run the application:
# On Windows
python app.py
On Linux/Mac
python3 app.py
Environment Variables
The.env file is intentionally included in this repository to facilitate easy setup for educational purposes. In a real-world application, you should never commit .env files to version control.
Current environment variables:
DBNAME=vulnerablebank DB_USER=postgres DB_PASSWORD=postgres DB_HOST=db # Change to 'localhost' for local installation DB_PORT=5432
Database Setup
The application uses PostgreSQL. The database will be automatically initialized when you first run the application, creating:- Users table
- Transactions table
- Loans table
Accessing the Application
- Main application:
http://localhost:5000 - API documentation:
http://localhost:5000/api/docs - GraphQL analytics endpoint:
http://localhost:5000/graphql - Admin analytics view: available from the admin dashboard after login as an admin user
Common Issues & Solutions
Windows
- If you get "python not found":
py instead of python
- Permission issues with uploads folder:
Linux/Mac
- Permission denied when creating directories:
sudo mkdir -p static/uploads
sudo chown -R $USER:$USER static/uploads
- Port 5000 already in use:
# Kill process using port 5000
sudo lsof -i:5000
sudo kill <PID>
PostgreSQL Issues
- Connection refused:
.env file
* Verify PostgreSQL port is not blocked
- Authentication failed:
DB_PASSWORD in .env matches your Postgres userβs password.
* Or reset the postgres user with:
ALTER ROLE postgres WITH PASSWORD 'your_password';
- Installation errors:
postgres:
choco install postgresql --version=17.4.0 -y
# Use the generated password, or immediately reset it:
& 'C:\Program Files\PostgreSQL\17\bin\psql.exe' -U postgres -c "ALTER ROLE postgres WITH PASSWORD 'postgres';"
- Database does not exist:
CREATE DATABASE vulnerable_bank;
* Or run:
createdb -U postgres -h localhost vulnerable_bank
Testing Guide π―
Authentication Testing
- SQL Injection in login
- Weak password reset (bruteforce 3-digit PIN)
- JWT token manipulation
- Username enumeration
- Token storage vulnerabilities
Authorization Testing
- Access other users' transaction history via account number
- Upload malicious files
- Access admin panel
- Manipulate JWT claims
- Exploit BOPLA (Excessive Data Exposure and Mass Assignment)
- Privilege escalation through registration
Transaction Testing
- Attempt negative amount transfers
- Race conditions in transfers
- Transaction history access
- Balance manipulation
File Upload Testing
- Upload unauthorized file types
- Attempt path traversal
- Upload oversized files
- Test file overwrite scenarios
- File type bypass
- SSRF: Use
/uploadprofilepicture_urlwith an internal or controlled URL
http://127.0.0.1:5000/internal/secret
- http://127.0.0.1:5000/internal/config.json
- http://127.0.0.1:5000/latest/meta-data/ (and subpaths like .../iam/security-credentials/)
- Blind SSRF: point to https://webhook.site/<your-id> and observe the incoming request
Example SSRF Flow
curl -s -X POST http://localhost:5000/uploadprofilepicture_url \
-H "Authorization: Bearer <JWT>" \
-H "Content-Type: application/json" \
-d '{"image_url":"http://127.0.0.1:5000/internal/secret"}'
-> Copy the returned filepath and GET http://localhost:5000/<filepath>
API Security Testing
- Token manipulation
- BOLA/BOPLA in API endpoints
- Information disclosure
- Error message analysis
GraphQL Testing
- Run schema introspection against
/graphql - Manipulate JWT claims to reach admin-scoped analytics
- Test SQL injection through GraphQL resolver inputs such as
accountNumber - Observe GraphQL error messages and path disclosure
- Test large or nested queries for missing depth / complexity controls
Virtual Card Testing
- Exploit mass assignment in card limit updates
- Manipulate
exchangeratein/api/virtual-cards/<cardid>/fundto over-credit a card during USD conversion - Analyze card number generation patterns
- Access unauthorized card details
- Test card freezing bypasses
- Transaction history manipulation
- Card limit validation bypass
Merchant Payment API Testing
The public merchant API lets intentionally vulnerable demo apps, such as ecommerce labs, accept payments from Vulnbank virtual cards.
Example Ecommerce Integration Flow
- Register or log in as a normal Vulnbank user.
- Create a virtual card and fund it from the user's main balance.
- Register a merchant integration from
http://localhost:5000/merchant/registeror by API:
curl -s -X POST http://localhost:5000/api/v1/merchants/register \
-H "Content-Type: application/json" \
-d '{"name":"Demo Ecommerce","email":"merchant@example.com","password":"password123"}'
- Charge the user's Vulnbank card from the ecommerce app using the merchant API key:
curl -s -X POST http://localhost:5000/api/v1/payments/charge \
-H "X-Merchant-Api-Key: <MERCHANTAPIKEY>" \
-H "Content-Type: application/json" \
-d '{
"amount": 49.99,
"currency": "USD",
"card_number": "4111111111111111",
"cvv": "123",
"expiry_date": "12/28",
"merchantorderid": "ORDER-1001",
"description": "Demo ecommerce checkout"
}'
- View the merchant dashboard at
http://localhost:5000/merchant/dashboard, or retrieve payment details with either the API key or the weak merchant JWT:
curl -s http://localhost:5000/api/v1/payments/<payment_id> \
-H "Authorization: Bearer <MERCHANT_JWT>"
Merchant Payment Attacks To Try
- Request another merchant's payment history through
/api/v1/payments/merchantid/<merchantid> - Compare
/api/v1/paymentswith/api/v1/payments/merchantid/<merchantid> - Replay the same charge request multiple times
- Submit negative payment amounts
- Trigger detailed decline reasons with invalid CVV, frozen cards, inactive cards, and insufficient balance
- Attempt SQL injection in merchant login, API key lookup, and raw card lookups
Bill Payment Testing
- Test biller enumeration
- Payment amount validation bypass
- Access unauthorized payment history
- SQL injection in biller selection
- Reference number prediction
- Race condition exploitation in payments
AI Customer Support Testing
Access the AI Chat: Look for the blue chat bubble in the bottom-right corner of the dashboard
Note: The chat widget has two modes:
- π Authenticated Mode: Includes your user context (more dangerous for real APIs)
- π€ Anonymous Mode: No personal data sent (still vulnerable to database access)
- Prompt Injection Attacks
- Information Disclosure via AI
- Authorization Bypass through AI
- AI System Exploitation
- Context Injection & Mode Testing
- Real-World Prompt Injection Techniques
Contributing π€
Contributions are welcome! Feel free to:
- Add new vulnerabilities
- Improve existing features
- Document testing scenarios
- Enhance documentation
- Fix bugs (that aren't intentional vulnerabilities)
π Blog Write-Up
A detailed walkthrough about this lab and my findings here: π Read the Blog By DghostNinja
(https://dghostninja.github.io/posts/Vulnerable-Bank-API/)
π Detailed Walkthrough by CyberPreacher
(https://medium.com/@cyberpreacher_/hacking-vulnerable-bank-api-extensive-d2a0d3bb209e)
Ethical hacking only. Scope respected. Coffee consumed. β
Disclaimer β οΈ
This application contains intentional security vulnerabilities for educational purposes. DO NOT:
- Deploy in production
- Use with real personal data
- Run on public networks
- Use for malicious purposes
- Store sensitive information
License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with β€οΈ for Security Education