6969d0c62e
VulnCheck - Open Source Vulnerability Management for Wazuh Features: - Vulnerability management with Wazuh integration - AI-powered CVE analysis (OpenAI, Anthropic, Google, DeepSeek, Ollama, Infomaniak) - SLA policy enforcement with automated email alerts - Automated patch verification via Wazuh Syscollector - Role-based access control (Admin, Editor, Readonly) - PDF/CSV reporting for compliance workflows - Full audit trail https://gitea.isuit.ch/vulncheck/vulncheck
11 KiB
11 KiB
VulnManager - Project Overview
🎯 Summary
VulnManager is a complete web application for prioritizing and managing security vulnerabilities. It integrates:
- Wazuh API for vulnerability data
- Infomaniak AI for AI-supported CVE analysis
- PostgreSQL as a database
- FastAPI as backend framework
📁 Project Structure
vulnerability-dashboard/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI Main App
│ ├── database.py # DB Connection
│ │
│ ├── models/ # SQLAlchemy Models
│ │ ├── __init__.py
│ │ ├── base.py # Base Model & Mixins
│ │ ├── user.py # User + RBAC
│ │ ├── asset.py # Asset/Inventory
│ │ ├── vulnerability.py # CVE Data
│ │ ├── scan.py # Scan History
│ │ ├── ai_analysis.py # AI Analyses (cached)
│ │ └── audit_log.py # Security Events
│ │
│ ├── auth/ # Authentication & Authorization
│ │ ├── __init__.py
│ │ ├── jwt_handler.py # JWT Token Management
│ │ └── dependencies.py # FastAPI Dependencies (RBAC)
│ │
│ ├── routers/ # API Endpoints
│ │ ├── __init__.py
│ │ ├── auth.py # Login, Logout, User Management
│ │ ├── vulnerabilities.py # CVE Management, AI Analysis
│ │ └── assets.py # Inventory Management
│ │
│ └── integrations/ # External APIs
│ ├── __init__.py
│ ├── wazuh_client.py # Wazuh API Client
│ └── infomaniak_ai_client.py # Infomaniak AI Client
│
├── alembic/ # Database Migrations
│ ├── env.py # Alembic Environment
│ ├── script.py.mako # Template for Migrations
│ └── versions/
│ └── 001_initial_schema.py # Initial DB Schema
│
├── alembic.ini # Alembic Config
├── requirements.txt # Python Dependencies
├── Dockerfile # Container Image
├── docker-compose.yml # Multi-Container Setup
├── .env.example # Environment Variables (Template)
├── .gitignore # Git Ignore
├── setup.sh # Setup Script
│
├── ARCHITECTURE.md # System Architecture
├── DATABASE_SCHEMA.md # DB Schema Documentation
├── README.md # Main Documentation
└── PROJECT_OVERVIEW.md # This File
🚀 Quick Start
# 1. Clone Repository
git clone <repo-url>
cd vulnerability-dashboard
# 2. Run Setup Script (creates .env, starts Docker, migrates DB)
chmod +x setup.sh
./setup.sh
# 3. Open API
open http://localhost:8000/docs
# 4. Login with Admin User
# Username: admin
# Password: changeme (PLEASE CHANGE!)
📊 Implemented Features
✅ Backend (FastAPI)
- JWT-based Authentication
- RBAC (Admin, Editor, Readonly)
- Vulnerability Management Endpoints
- Asset Inventory Endpoints
- Dashboard Statistics
- Audit Logging
- Rate Limiting
- Security Headers (OWASP)
✅ Wazuh Integration
- API Client with Auto-Authentication
- Agent Discovery
- Vulnerability Sync
- Syscollector Rescan Trigger
- Patch Verification Workflow
✅ Infomaniak AI Integration
- CVE Analysis with Web Search
- Threat Intelligence Aggregation
- Exploit Detection
- Remediation Recommendations
- Caching (24h TTL)
✅ Database
- PostgreSQL Schema with 6 Tables
- Alembic Migrations
- Foreign Key Constraints
- Composite Indices
- Audit Trail
✅ Security (OWASP Top 10)
- A01: Broken Access Control → JWT + RBAC
- A02: Cryptographic Failures → bcrypt, TLS
- A03: Injection → SQLAlchemy ORM
- A04: Insecure Design → Rate Limiting
- A05: Security Misconfiguration → Security Headers
- A07: Authentication Failures → Account Lockout
- A09: Logging Failures → Audit Logs
✅ Deployment
- Dockerfile (Non-Root-User)
- Docker Compose (Backend + DB + Redis)
- Environment Variables
- Health Checks
- Setup Script
🔧 Configuration
Environment Variables (.env)
# Database
DATABASE_URL=postgresql://user:pass@host:5432/db
# JWT
JWT_SECRET_KEY=<256-bit-random-key>
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
# Wazuh
WAZUH_API_URL=https://wazuh.example.com:55000
WAZUH_API_USERNAME=api-user
WAZUH_API_PASSWORD=changeme
# Infomaniak AI
INFOMANIAK_AI_API_KEY=<your-key>
INFOMANIAK_AI_MODEL=gpt-4o
# Security
CORS_ORIGINS=http://localhost:3000
ALLOWED_HOSTS=localhost,127.0.0.1
📡 API Overview
Authentication
POST /auth/login- Login (JWT-Token)POST /auth/logout- LogoutPOST /auth/refresh- Token RefreshGET /auth/me- Current UserPOST /auth/register- Create User (Admin)POST /auth/change-password- Change Password
Vulnerabilities
GET /api/v1/vulnerabilities- List (with Filter, Sort, Pagination)GET /api/v1/vulnerabilities/{id}- Details + AI AnalysisPATCH /api/v1/vulnerabilities/{id}- Change Status (Patch)POST /api/v1/vulnerabilities/{id}/analyze- Trigger AI AnalysisPOST /api/v1/vulnerabilities/sync/wazuh- Synchronize Wazuh DataGET /api/v1/vulnerabilities/reports/dashboard- Dashboard Stats
Assets
GET /api/v1/assets- ListGET /api/v1/assets/{id}- DetailsPOST /api/v1/assets- Create Manual AssetPUT /api/v1/assets/{id}- UpdateDELETE /api/v1/assets/{id}- Delete (Admin)GET /api/v1/assets/{id}/vulnerabilities- CVEs of an Asset
Health
GET /health- Health CheckGET /- API Info
🔒 RBAC Permissions
Admin (UserRole.ADMIN)
- All Rights
- User Management (create, delete)
- System Configuration
- Delete Assets
Editor (UserRole.EDITOR)
- Manage Vulnerabilities (Change Status)
- Create/Update Assets
- Trigger Scans
- Request AI Analyses
Readonly (UserRole.READONLY)
- View Dashboard
- Read Vulnerabilities
- Read Assets
- Generate Reports
🗄️ Database Schema (PostgreSQL)
Tables
- users - Users + RBAC
- assets - Inventory (Wazuh + Manual)
- vulnerabilities - CVEs with CVSS, Severity, Status
- scans - Scan History
- ai_analyses - AI Analyses (cached, 24h TTL)
- audit_logs - Security Events
Important Fields
vulnerabilities:
cve_id- CVE Identifiercvss_score- CVSS Score (0.0-10.0)severity- Critical, High, Medium, Lowstatus- Open, Patched, Pending Verification, etc.exploitable- Boolexploit_available- Boolpriority_score- Calculated: CVSS + Exploitability + Age
Priority Score Calculation:
Priority = (CVSS × 5) + (Exploitability × 30) + (Age × 20)
= 0-50 + 0-30 + 0-20
= 0-100 Points
🎨 Workflow Examples
1. Patch Verification
1. User: PATCH /vulnerabilities/123 {status: "patched"}
2. Backend: Status → "pending_verification"
3. Background Task: Wazuh Syscollector Rescan
4. Wait for Scan Completion (max. 10 Min)
5. Re-fetch Vulnerability Data
6. Check: CVE still present?
→ No: Status → "patched" ✅
→ Yes: Status → "patch_failed" ❌
2. AI Analysis
1. User: POST /vulnerabilities/123/analyze
2. Cache Check (24h TTL)
→ Hit: Return cached Analysis
→ Miss: Continue
3. Call Infomaniak AI API with:
- CVE-ID
- Package Name/Version
- CVSS Score
4. LLM with Web Search generates:
- Threat Level
- Exploits (URLs, PoC Status)
- Workarounds
- Remediation Steps
- Threat Intel Sources
5. Parse JSON Response
6. Save in DB (ai_analyses)
7. Return Analysis
3. Wazuh Sync
1. User: POST /vulnerabilities/sync/wazuh
2. Background Task:
a. Get all active Wazuh Agents
b. For each Agent:
- Get or create Asset (hostname, IP, OS)
- Fetch Vulnerabilities (GET /vulnerability/{agent_id})
- Upsert in DB (deduplicated by CVE + Asset)
c. Update Asset.last_scan
3. Return: {message: "Sync started"}
🚧 Known Limitations
Currently NOT implemented:
- ✅ Frontend (Next.js Dashboard)
- ❌ Multi-Tenancy
- ❌ Notifications (Slack, E-Mail)
- ❌ Report Export (PDF, CSV)
- ❌ MFA (Multi-Factor Authentication)
- ❌ Token Blacklist (for Logout)
- ❌ Compliance Modules (ISO 27001, PCI-DSS)
Workarounds:
- Frontend: Use Swagger UI (http://localhost:8000/docs)
- Notifications: Implement Webhooks (e.g. Zapier)
- Reports: Export via API + Python Script
- Token Blacklist: Implement Redis-based Blacklist
🛠️ Development
Writing Tests
# tests/test_vulnerabilities.py
import pytest
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_list_vulnerabilities():
response = client.get("/api/v1/vulnerabilities")
assert response.status_code == 401 # Unauthorized (no Token)
def test_login():
response = client.post("/auth/login", json={
"username": "admin",
"password": "changeme"
})
assert response.status_code == 200
assert "access_token" in response.json()
Adding New Endpoint
# app/routers/vulnerabilities.py
@router.get("/statistics/severity")
async def get_severity_distribution(db: Session = Depends(get_db)):
"""Severity Distribution as Chart Data"""
stats = db.query(
Vulnerability.severity,
func.count(Vulnerability.id)
).group_by(Vulnerability.severity).all()
return {s[0]: s[1] for s in stats}
📈 Performance Optimizations
Implemented:
- ✅ Connection Pooling (SQLAlchemy)
- ✅ Composite Indices (status + severity)
- ✅ AI Analysis Caching (24h)
- ✅ Lazy Loading of Relations
To Be Implemented:
- Redis Caching for Dashboard Stats
- Pagination via Cursor (instead of Offset)
- Background Jobs with Celery
- Read Replicas for Reports
📚 Further Documentation
- ARCHITECTURE.md - System Architecture
- DATABASE_SCHEMA.md - DB Schema Details
- README.md - Installation & Usage
- API Docs: http://localhost:8000/docs (Swagger)
🐛 Debugging
View Logs
# Backend Logs
docker-compose logs -f backend
# All Services
docker-compose logs -f
# PostgreSQL Logs
docker-compose logs -f postgres
Enter Container
# Backend
docker-compose exec backend bash
# PostgreSQL
docker-compose exec postgres psql -U vulnmanager
Reset Database
docker-compose down -v # Deletes Volumes too!
docker-compose up -d
./setup.sh
📧 Support
For questions or problems:
- Check README.md Troubleshooting Section
- Open Issue on GitHub
- Contact: security@example.com
Status: ✅ Production Ready (v1.0.0)
Created: January 2025
License: MIT