Educational platform showcasing OWASP API Security Top 10 (2023) vulnerabilities
Quick Start β’ Vulnerabilities β’ Learning Guide β’ Docker Hub
APIGOAT is a deliberately vulnerable RESTful API designed for penetration testing training, exploit demonstrations, and secure coding education. Built with Node.js, Express.js, and MongoDB, packaged in a single Docker container for zero-configuration deployment.
Key Features:
- π― Complete OWASP API Top 10 (2023) coverage
- π³ Single Docker image (Node.js 18 + MongoDB 7.0 + 10 APIs + Web UI)
- π One-command deployment from Docker Hub
- π Isolated environment safe for exploitation
- π Interactive documentation and exploit examples
- π» Cross-platform (Windows, Linux, macOS)
Originally initiated under OWASP Bursa Technical University Student Chapter
Developed and maintained by Yusuf Talha ArabacΔ±
docker run -d --name apigoat -p 8000-8010:8000-8010 -p 27017:27017 yusufarbc/apigoat:latestAccess at http://localhost:8000 (ready in 10-15 seconds)
Click to expand build instructions
Prerequisites: Docker Desktop (Windows/Mac) or Docker Engine (Linux)
# Clone repository
git clone https://github.com/yusufarbc/apigoat.git
cd apigoat
# Windows
.\start.ps1
# Linux/macOS
docker build -t apigoat:all .
docker run -d --name apigoat-all -p 8000-8010:8000-8010 -p 27017:27017 apigoat:allFirst build: 2-3 minutes | Subsequent runs: 10-15 seconds
docker logs -f apigoat # View logs
docker stop apigoat # Stop container
docker rm apigoat # Remove container
docker restart apigoat # Restartββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Single Docker Container (~1.2GB) β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Node.js 18 (Ubuntu 22.04) β β
β β ββ MongoDB 7.0 (embedded, port 27017) β β
β β ββ Web UI (port 8000) β β
β β ββ API1-10 (ports 8001-8010) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Tech Stack:
- Runtime: Node.js 18 | Framework: Express.js 4.19.2
- Database: MongoDB 7.0 | ODM: Mongoose 8.4.5
- Auth: JWT 9.0.2 + bcrypt 5.1.1
| API | Port | OWASP Category | Vulnerability |
|---|---|---|---|
| API1 | 8001 | Broken Object Level Authorization (BOLA) | Access other users' files without ownership validation |
| API2 | 8002 | Broken Authentication | Clear-text credentials over HTTP, no rate limiting |
| API3 | 8003 | Broken Object Property Level Authorization | Expose sensitive properties (isAdmin, private posts) |
| API4 | 8004 | Unrestricted Resource Consumption | No pagination or rate limiting β DoS vulnerability |
| API5 | 8005 | Broken Function Level Authorization | Authentication middleware bypassed (next() always called) |
| API6 | 8006 | Unrestricted Access to Business Flows | View all flight bookings without authentication |
| API7 | 8007 | Server Side Request Forgery (SSRF) | User-controlled URLs in server-side requests |
| API8 | 8008 | Security Misconfiguration | Permissive CORS, debug endpoints exposed |
| API9 | 8009 | Improper Inventory Management | Undocumented /unknown endpoint |
| API10 | 8010 | Unsafe Consumption of APIs | Hardcoded API keys, unsanitized external responses |
Recommended Path:
-
API1 - BOLA (Start Here)
# Create two users curl -X POST http://localhost:8001/signup \ -H "Content-Type: application/json" \ -d '{"name":"Alice","email":"[email protected]","password":"secret"}' # Access other users' files with Alice's token curl http://localhost:8001/files/2 \ -H "Content-Type: application/json" \ -d '{"token":"<alice_token>"}'
-
API7 - SSRF
# Access internal services curl "http://localhost:8007/weather?location=http://mongodb:27017" # Attempt cloud metadata curl "http://localhost:8007/weather?location=http://169.254.169.254/latest/meta-data/"
Security Tools:
- Burp Suite - Intercept and modify requests
- OWASP ZAP - Automated scanning
- Postman - API testing
- curl/httpie - Command-line testing
Secure Coding Checklist:
- β Validate ownership before resource access (fix BOLA)
- β Implement proper authentication middleware (fix API5)
- β Apply rate limiting and pagination (fix API4)
- β Filter sensitive properties from responses (fix API3)
- β Validate and sanitize external API responses (fix API10)
- β Restrict CORS to known origins (fix API8)
Code Review Exercise:
# Study vulnerable patterns
1. API5/check-auth.js - Bypassed authentication
2. API1/routes.js - Missing ownership check
3. API4/routes.js - No pagination limits
4. API7/routes.js - SSRF via user inputResources:
| β NEVER | β ALWAYS |
|---|---|
| Deploy to production | Use in isolated lab environments |
| Expose to public networks | Keep on local Docker networks |
| Use with real data | Use sample/test data only |
| Connect to production systems | Run on dedicated training machines |
Safe Usage:
# β
Good: Local isolated environment
docker run -d --name apigoat -p 8000-8010:8000-8010 -p 27017:27017 yusufarbc/apigoat
# β Bad: Exposing to public network
docker run -d --name apigoat -p 0.0.0.0:8000:8000 ... # DON'T!Database Access
# Connect from host
mongosh mongodb://localhost:27017/apigoat
# Connect from inside container
docker exec -it apigoat mongosh --eval "db.getMongo().getDBNames()"
# Backup
docker exec apigoat mongodump --out /tmp/backupTroubleshooting
Port conflicts:
# Check port usage
netstat -ano | findstr :8000 # Windows
lsof -i :8000 # Linux/Mac
# Use different ports
docker run -d -p 9000-9010:8000-8010 ... yusufarbc/apigoatContainer issues:
# View logs
docker logs apigoat
# Restart
docker restart apigoat
# Full cleanup
docker stop apigoat && docker rm apigoat
docker image prune -aDebug mode:
# Enter container
docker exec -it apigoat /bin/bash
# Check services
tail -f /var/log/api1.log
tail -f /var/log/mongodb.log
ps aux | grep nodePerformance Optimization
MongoDB Indexes (add to models for production-like scenarios):
accountSchema.index({ email: 1 }, { unique: true });
filesSchema.index({ number: 1 });
bookSchema.index({ name: 1, author: 1 });Compression (add to app.js):
const compression = require('compression');
app.use(compression());Current Metrics:
- Container Size: ~1.2 GB
- Memory Usage: ~300-400 MB idle
- Startup Time: 10-15 seconds
- Can handle 100+ concurrent requests per API
Contributions welcome! Ways to help:
- π Report bugs via GitHub Issues
- π‘ Suggest new vulnerability patterns
- π Improve documentation
- π Add OWASP coverage examples
- π§ͺ Write security test cases
Quick Development Setup:
git clone https://github.com/YOUR_USERNAME/apigoat.git
cd apigoat
git checkout -b feature/your-feature
# Test changes
docker build -t apigoat:test .
docker run -d --name apigoat-test -p 8000-8010:8000-8010 apigoat:test
# Submit PR
git commit -m "Add: Description"
git push origin feature/your-featurePR Checklist:
- Code builds without errors
- Container starts successfully
- Changes documented with comments
- README updated (if needed)
- Vulnerabilities remain intact (no accidental fixes!)
Licensed under GNU General Public License v3.0 (GPL-3.0)
- β Use, modify, and distribute freely
- β Must disclose source code
- β Same license for derivatives
- β State changes made
See LICENSE for full details.
Yusuf Talha ArabacΔ±
Cyber Security Engineer
Originally initiated under OWASP Bursa Technical University Student Chapter
- OWASP Foundation - API Security Top 10 2023 framework
- OWASP Bursa Technical University - Project initiation support
- Open Source Community - Tools and libraries
- π GitHub Issues
- π¬ GitHub Discussions
- π§ Email via GitHub profile
- π³ Docker Hub
β If this helped you learn API security, please star the repo! β
Made with β€οΈ for the security community
Learn to break, learn to build better.