This is an intentionally vulnerable web application designed for Capture The Flag (CTF) challenges. The application features a modern React frontend and contains a deliberate SQL injection vulnerability for educational purposes.
This application is INTENTIONALLY VULNERABLE and should NEVER be deployed in a production environment. It is designed for educational purposes and CTF challenges only.
https://medusa-ctf-production.azurewebsites.net/
Goal: Login as the admin user without knowing the password
Flag: Medusa{CTF_CHALLENGE_PHASE1_PASSED} (sent as HTTP response header)
Vulnerability: SQL Injection in the login form
Frontend: Modern React application with Vite build system
- Frontend: React 19 with Vite
- Backend: Node.js with Express
- Database: SQLite
- Deployment: Azure App Service with Docker
- CI/CD: GitHub Actions with Automated Cleanup
This project includes several automated GitHub Actions workflows for seamless deployment and resource management:
- β Triggers on every push to any branch
- β Creates unique deployments per commit
- β Automatically cleans up old deployments after each push
- β Keeps only the latest deployment
- β Focused on main branch deployments
- β Intelligent cleanup logic
- β Can be run manually for cleanup-only operations
- β Comprehensive deployment summaries
- β Runs daily at 3 AM UTC
- β Ensures only the latest deployment remains
- β Prevents resource accumulation
- β Can be triggered manually anytime
- β Handles main branch and PR deployments
- β Includes post-deployment cleanup
- β SQL injection testing
- β Deployment verification
- β On-demand cleanup workflow
- β Works with scheduled runs
- β Detailed cleanup reports
All workflows automatically:
- π§Ή Keep only the most recently created Azure web app
- ποΈ Delete all older deployments
- π§ͺ Test the remaining deployment
- π Provide detailed reports in GitHub Actions summaries
./restart.shThis script will automatically:
- Stop and cleanup existing containers
- Rebuild the database
- Build React frontend and Docker container
- Run automated tests
- Show application status
Script Options:
./restart.sh --help # Show help
./restart.sh --no-tests # Skip running tests
./restart.sh --cleanup-only # Only cleanup, don't restart- Build and start (includes React build):
docker-compose up --build -d- Access the application:
http://localhost:3000
- Build the Docker container (includes React build):
docker build -t vulnerable-ctf-app .- Run the container:
docker run -d -p 3000:3000 --name ctf-challenge vulnerable-ctf-app- Access the application:
http://localhost:3000
- Install dependencies:
npm install- Set up the database:
npm run setup- Build React frontend:
npm run build- Set the flag environment variable (optional):
export CTF_FLAG="Medusa{CTF_CHALLENGE_PHASE1_PASSED}"- Start the server:
npm start- Access the application:
http://localhost:3000
For development with hot reloading:
- Start the backend server:
npm run dev- In another terminal, start the React dev server:
npm run dev-frontend- Access the React dev server:
http://localhost:5173
The restart.sh script provides a convenient way to completely restart the CTF application:
# Full restart with tests
./restart.sh
# Restart without running tests
./restart.sh --no-tests
# Only cleanup existing containers
./restart.sh --cleanup-only
# Show help
./restart.sh --helpWhat the script does:
- π§Ή Stops and removes existing containers/images
- ποΈ Rebuilds the SQLite database from scratch
- π³ Builds and starts the Docker container
- π§ͺ Runs automated SQL injection tests
- π Shows application status and access information
The application uses environment variables for secure flag management:
CTF_FLAG: The flag to display upon successful exploitation (default: "Medusa{CTF_CHALLENGE_PHASE1_PASSED}")PORT: Server port (default: 3000)NODE_ENV: Node.js environment (default: development)
-
Navigate to
http://localhost:3000 -
Try to login with normal credentials:
- Username:
guest - Password:
guest - Expected: "Invalid credentials" (because guest is not admin)
- Username:
-
Try SQL injection to bypass authentication:
- Username:
admin' OR '1'='1' -- - Password:
anything - Expected: Success message displayed
- Flag location: Check the
X-CTF-FlagHTTP response header
- Username:
Finding the Flag:
The flag is sent as an HTTP response header named X-CTF-Flag. Use browser developer tools (Network tab) or tools like curl to inspect the response headers:
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username":"admin\' OR \'1\'=\'1\' --","password":"anything"}' \
-vRun the test script:
node test-sqli.jsHere are some SQL injection payloads you can test:
-
Basic OR bypass:
Username: admin' OR '1'='1' -- Password: anything -
Comment-based bypass:
Username: admin'-- Password: anything -
Union-based (advanced):
Username: admin' UNION SELECT 1,'admin','password' -- Password: anything
Even though the application is vulnerable to SQL injection, it includes several security hardening measures:
- Containerization: Runs in isolated Docker container
- Non-root user: Container runs as non-privileged user
- Read-only database: Database file is set to read-only to prevent DROP TABLE attacks
- Header security: X-Powered-By header is disabled
- Principle of least privilege: Minimal permissions and access
vulnerable-ctf-app/
βββ frontend/
β βββ src/
β β βββ App.jsx # Main React component
β β βββ main.jsx # React entry point
β β βββ index.css # Styling (Matrix theme)
β βββ index.html # HTML template
βββ dist/ # Built React files (generated)
βββ src/
β βββ index.html # Legacy HTML (kept for reference)
βββ database-setup.js # Database initialization script
βββ server.js # Express server with vulnerable endpoint
βββ package.json # Node.js dependencies
βββ vite.config.js # Vite build configuration
βββ Dockerfile # Container configuration (includes React build)
βββ docker-compose.yml # Docker Compose configuration
βββ restart.sh # One-command restart script
βββ test-sqli.js # Automated test script
βββ README.md # This file
The React frontend includes:
- Modern component-based architecture
- Loading states for better UX
- Enhanced error handling and display
- Responsive design with Matrix-inspired styling
- Proper form validation
- CTF flag display with visual emphasis
- Automatic redirection after successful login
# Backend
npm start # Start production server
npm run dev # Start development server with flag
npm run setup # Initialize database
# Frontend
npm run build # Build React app for production
npm run dev-frontend # Start React dev server
npm run preview # Preview built React app
# Combined
npm run build-and-start # Build React + start serverThe vulnerability exists in the /login endpoint in server.js:
// VULNERABLE CODE - DO NOT USE IN PRODUCTION
const query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";This code directly concatenates user input into the SQL query without sanitization, allowing attackers to inject malicious SQL code.
- Direct string concatenation in SQL queries
- No input validation or sanitization
- No use of parameterized queries
- Use parameterized queries/prepared statements
- Input validation and sanitization
- Implement proper authentication mechanisms
- Use ORM libraries that prevent SQL injection
./restart.sh --cleanup-onlyTo stop and remove the Docker container:
docker-compose down
# or
docker stop ctf-challenge
docker rm ctf-challengeTo remove the Docker image:
docker rmi vulnerable-ctf-appThis application is provided for educational purposes only. Users are responsible for ensuring this application is used only in authorized testing environments. The creators are not responsible for any misuse of this vulnerable application.