Technical‐Architecture - capstone-hermes/hermes-fullstack GitHub Wiki
Technical Architecture
System Overview
The Weak Website follows a modern three-tier architecture with intentional security vulnerabilities for educational purposes. The system is containerized using Docker for easy deployment and isolation.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ React Client │◄──►│ NestJS Server │◄──►│ MySQL Database │
│ (Port 8081) │ │ (Port 8080) │ │ (Port 3306) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
┌─────────────────┐
│ Docker Compose │
│ Orchestration │
└─────────────────┘
Technology Stack
Frontend (Client)
- Framework: React 18.3.1
- Language: TypeScript 5.5.3
- Build Tool: Vite 5.4.1
- UI Library: ShadCN UI with Radix UI primitives
- Styling: TailwindCSS 3.4.11
- State Management: TanStack Query 5.56.2
- Routing: React Router DOM 6.30.0
- Form Handling: React Hook Form 7.53.0 + Zod validation
Backend (Server)
- Framework: NestJS 10.0.0
- Language: TypeScript 5.1.3
- Database ORM: TypeORM 0.3.20
- Authentication: JSON Web Tokens (jsonwebtoken 9.0.2)
- Validation: class-validator 0.14.1
- API Documentation: Swagger/OpenAPI (@nestjs/swagger 8.1.0)
- Testing: Jest 29.5.0 + Supertest 7.0.0
Database
- Engine: MySQL 8.0+
- Connection: TypeORM with connection pooling
- Schema Management: Auto-synchronization (development)
- Data Persistence: Docker volumes
Infrastructure
- Containerization: Docker + Docker Compose
- Development: Hot-reload for both client and server
- Production: Multi-stage Dockerfiles for optimization
- Networking: Internal Docker network isolation
Project Structure
Repository Layout
hermes-fullstack/
├── weak-website/
│ ├── client/ # React frontend application
│ ├── server/ # NestJS backend application
│ ├── docker-compose.dev.yml # Development configuration
│ └── README.md # Project documentation
├── gui/ # Scanner GUI application
├── web-scanner/ # Python vulnerability scanner
└── docker-compose.yml # Multi-service orchestration
Client Architecture
client/
├── src/
│ ├── components/ # Reusable UI components
│ │ ├── ui/ # ShadCN UI component library
│ │ ├── Layout.tsx # Main application layout
│ │ ├── PostForm.tsx # Post creation form
│ │ ├── PostList.tsx # Feed display component
│ │ └── ProtectedRoute.tsx # Authentication guard
│ ├── pages/ # Route-based page components
│ │ ├── Index.tsx # Landing page
│ │ ├── Login.tsx # Authentication page
│ │ ├── Signup.tsx # User registration
│ │ ├── Dashboard.tsx # User dashboard
│ │ ├── Feed.tsx # Social feed
│ │ ├── FileUpload.tsx # File upload interface
│ │ └── SecurityInfo.tsx # Vulnerability documentation
│ ├── services/ # API communication layer
│ │ └── api.ts # HTTP client and endpoints
│ ├── types/ # TypeScript type definitions
│ │ ├── auth.ts # Authentication types
│ │ └── post.ts # Post-related types
│ ├── utils/ # Utility functions
│ │ └── auth.ts # Authentication helpers
│ ├── routes/ # Routing configuration
│ │ └── routes.tsx # React Router setup
│ └── hooks/ # Custom React hooks
└── public/ # Static assets
Server Architecture
server/
├── src/
│ ├── modules/ # Feature-based modules
│ │ ├── auth/ # Authentication & authorization
│ │ │ ├── auth.controller.ts
│ │ │ ├── auth.service.ts
│ │ │ ├── auth.module.ts
│ │ │ ├── jwt-auth.guard.ts
│ │ │ ├── password.helper.ts
│ │ │ └── dtos/
│ │ ├── user/ # User management
│ │ │ ├── user.controller.ts
│ │ │ ├── user.service.ts
│ │ │ ├── user.entity.ts
│ │ │ ├── user.module.ts
│ │ │ └── dtos/
│ │ ├── file/ # File upload/download
│ │ │ ├── file.controller.ts
│ │ │ └── file.module.ts
│ │ ├── input/ # Input validation demos
│ │ ├── redirect/ # URL redirection
│ │ └── validation/ # Validation examples
│ ├── post/ # Social posting feature
│ │ ├── post.controller.ts
│ │ ├── post.service.ts
│ │ ├── post.entity.ts
│ │ ├── post.module.ts
│ │ └── dtos/
│ ├── vulnerable-exception.filter.ts # Error handling flaws
│ ├── vulnerable-params.middleware.ts # Parameter pollution
│ ├── app.module.ts # Main application module
│ └── main.ts # Application entry point
├── certs/ # SSL certificates
├── test/ # E2E and unit tests
└── dist/ # Compiled JavaScript output
Data Flow Architecture
Request Processing Pipeline
1. Client Request
│
├── React Component
│ └── TanStack Query
│ └── API Service Layer
│
2. Network Layer
│
├── HTTP Request (Axios)
│ └── JSON Payload
│
3. Server Processing
│
├── NestJS Controller
│ ├── Vulnerable Middleware (Parameter Pollution)
│ ├── Route Handler
│ └── DTO Validation (Minimal)
│
4. Business Logic
│
├── Service Layer
│ ├── Raw SQL Queries (Vulnerable)
│ └── Business Logic
│
5. Data Persistence
│
├── TypeORM Repository
│ └── MySQL Database
│
6. Response Generation
│
├── Unfiltered Data
│ └── Error Information Exposure
│
7. Client Response
│
└── React State Update
└── UI Re-render
Authentication Flow
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Client │ │ Server │ │ Database │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ POST /auth/login │ │
├──────────────────►│ │
│ {email, password} │ │
│ │ Raw SQL Query │
│ ├──────────────────►│
│ │ (SQL Injection) │
│ │ │
│ │ User Data │
│ │◄──────────────────┤
│ │ │
│ │ JWT Generation │
│ │ (Hardcoded Secret)│
│ │ │
│ JWT Token │ │
│◄──────────────────┤ │
│ │ │
│ Subsequent │ │
│ Requests with │ │
│ Bearer Token │ │
├──────────────────►│ │
Database Schema
Entity Relationship Diagram
┌─────────────────┐ ┌─────────────────┐
│ User │ │ Post │
├─────────────────┤ ├─────────────────┤
│ id (PK) │◄───┤ id (PK) │
│ email │ │ content │
│ password │ │ userId (FK) │
│ role │ │ createdAt │
│ createdAt │ └─────────────────┘
└─────────────────┘
User Entity
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({ unique: true })
email: string;
@Column()
password: string; // Stored in plain text (vulnerability)
@Column({ default: 'user' })
role: string;
@CreateDateColumn()
createdAt: Date;
@OneToMany(() => Post, post => post.user)
posts: Post[];
}
Post Entity
@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;
@Column('text')
content: string; // No sanitization (vulnerability)
@Column()
userId: number;
@CreateDateColumn()
createdAt: Date;
@ManyToOne(() => User, user => user.posts)
user: User;
}
Security Architecture (Intentionally Vulnerable)
Authentication Vulnerabilities
// auth.service.ts:24-26
async login(email: string, password: string) {
// SQL Injection vulnerability
const user = await this.userRepository.query(
`SELECT * FROM user WHERE email = '${email}' AND password = '${password}'`
);
// Hardcoded JWT secret
const token = jwt.sign({ userId: user[0].id }, 'hardcoded-secret');
return { token };
}
Parameter Pollution Middleware
// vulnerable-params.middleware.ts
@Injectable()
export class VulnerableParamsMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
// Last parameter wins - enables parameter pollution
if (req.body && typeof req.body === 'object') {
Object.keys(req.body).forEach(key => {
if (Array.isArray(req.body[key])) {
req.body[key] = req.body[key][req.body[key].length - 1];
}
});
}
next();
}
}
File Upload Vulnerabilities
// file.controller.ts:38-52
@UseInterceptors(
FileInterceptor('file', {
storage: diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
// Use user-submitted filename directly (vulnerability)
const filename = file.originalname;
cb(null, filename);
},
}),
// No file size limit (vulnerability)
limits: {
fileSize: 1024 * 1024 * 1000, // 1GB
},
}),
)
API Architecture
RESTful Endpoint Structure
/auth
├── POST /login # User authentication
├── POST /signup # User registration
└── POST /change-password # Password modification
/users
├── GET /profile # User profile information
└── POST /create # User creation (admin)
/posts
├── GET /all # Retrieve all posts
├── POST /create # Create new post
└── DELETE /:id # Delete post
/file
├── POST /upload # File upload
├── GET /download/:filename # File download
├── GET /retrieve # Path traversal endpoint
├── GET /remote # Remote file inclusion
├── POST /execute # Command injection
└── GET /backup/:filename # Backup file access
/validation
├── GET /input # Input validation demos
├── POST /reflect # Reflection vulnerabilities
└── GET /header # Header injection
/redirect
└── GET /to # Open redirect vulnerability
Request/Response Flow
Client Request → Middleware → Controller → Service → Repository → Database
↓
Parameter Pollution
↓
Business Logic (Vulnerable)
↓
Raw SQL Execution
↓
Unfiltered Response ← Error Disclosure ← Exception Filter
Deployment Architecture
Docker Compose Configuration
services:
db:
image: mysql:latest
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD}
- MYSQL_DATABASE=${DB_DATABASE}
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
server:
build: ./server
ports:
- "8080:8080"
depends_on:
- db
environment:
- DB_HOST=db
- JWT_SECRET=${JWT_SECRET}
client:
build: ./client
ports:
- "8081:8081"
depends_on:
- server
environment:
- VITE_SERVER_URL=http://localhost:8080
Network Architecture
Host Network
├── Client Container (8081)
├── Server Container (8080)
└── Database Container (3306)
│
└── Internal Docker Network
├── app-network (bridge)
└── Volume: mysql-data
Environment Configuration
# Development
DB_HOST=db
DB_PORT=3306
DB_USER=user
DB_PASSWORD=password
DB_DATABASE=hermes-weak-website-db
JWT_SECRET=hardcoded-secret
SERVER_PORT=8080
CLIENT_PORT=8081
Performance Characteristics
Database Performance
- Connection Pooling: TypeORM default pool (10 connections)
- Query Optimization: None (intentionally inefficient)
- Indexing: Minimal (only primary keys)
- Transactions: Limited support
Server Performance
- Concurrent Requests: Limited by security overhead
- Memory Usage: Unoptimized for demonstration
- Response Times: Degraded by vulnerable operations
- Throughput: Reduced by extensive logging
Client Performance
- Bundle Size: ~2MB (modern React stack)
- Initial Load: ~3 seconds (unoptimized)
- Runtime Performance: Good (React 18 features)
- Caching: Browser cache only
Development Workflow
Local Development
# Client development
cd client
npm install
npm run dev # http://localhost:8081
# Server development
cd server
npm install
npm run start:dev # http://localhost:8080
# Database
docker run -d \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=hermes-weak-website-db \
-p 3306:3306 \
mysql:latest
Build Process
# Production builds
cd client && npm run build
cd server && npm run build
# Docker builds
docker-compose up --build
Testing Strategy
- Unit Tests: Jest for service layer logic
- Integration Tests: Supertest for API endpoints
- E2E Tests: Manual security testing
- Vulnerability Testing: Intentional security flaw verification
Security Considerations
Intentional Vulnerabilities
The application deliberately implements these security flaws:
- SQL injection in authentication
- XSS in post content
- Path traversal in file operations
- Parameter pollution in all endpoints
- Weak JWT implementation
- Information disclosure in errors
- Command injection in file operations
Isolation Requirements
- Use Docker networks for isolation
- Never expose to public networks
- Implement firewall rules for container access
- Monitor for accidental exposure
Monitoring and Logging
Application Logging
// Excessive logging for education
this.logger.log(`User logged in: ${email}:${password}`);
this.logger.log(`Token generated: ${token}`);
this.logger.log(`File uploaded: ${filename} by ${authorization}`);
Security Event Logging
- Authentication attempts (including credentials)
- File operations with full paths
- SQL queries with user input
- Error details with stack traces
Extensions and Customization
Adding New Vulnerabilities
- Create new module in
server/src/modules/
- Implement vulnerable endpoint
- Add corresponding client interface
- Document vulnerability in wiki
- Add to OWASP ASVS mapping
Educational Enhancements
- Add more OWASP Top 10 examples
- Implement additional ASVS requirements
- Create guided exploitation tutorials
- Add vulnerability scanning integration
Next: Continue to Database Schema for detailed data modeling or API Reference for endpoint documentation.