Skip to content
 
 

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VulNex — LLM-Powered Vulnerability Detection Tool

A full-stack security scanner that combines Bandit + Semgrep static analysis with Google Gemini AI-powered explanations, a tamper-evident Evidence Chain audit trail, and PDF/Excel report export.


Screenshots

Upload & Scan

Upload any code file and hit Start Security Scan — VulNex immediately begins a 3-stage pipeline.

Screenshot (335)

Real-time Scan Progress

Watch Static Analysis → AI Analysis → CVE Mapping complete live.

Screenshot (336) Screenshot (337)

Detected Vulnerabilities Table

Paginated, filterable, searchable table of every finding.

Screenshot (338)

Security Report (PDF)

Executive Summary, Severity Breakdown, Vulnerability Summary table, and per-finding detail pages.

Screenshot (339) Screenshot (340) Screenshot (341)

Report Generator UI (with chain-of-custody)

Screenshot (342)

Screenshots were captured from a live run scanning sample_vulnerable_app.py (31 findings, August 2026).


Features

Feature Details
Multi-language scanning .py .js .ts .java .cpp .c .cs .rb .php .go .rs + ZIP archives
Static analysis Bandit (Python) + Semgrep (multi-language)
AI analysis Google Gemini — per-finding explanations, suggested code fixes, confidence scores
CVE/CWE mapping Automatic mapping to CWE IDs and OWASP Top 10 categories
Evidence Chain Tamper-evident SHA-256 hash-chained audit trail per finding (see below)
Verification endpoint Walk the chain and recompute all hashes to confirm integrity
Report export PDF (ReportLab) and Excel (openpyxl) with chain-of-custody summary
Mark as reviewed Per-finding review flag, also logged to the evidence chain
Real-time progress Live 3-stage pipeline progress with polling

Evidence Chain Module

Every vulnerability finding gets a tamper-evident audit trail. Each lifecycle event (detected, reviewed, exported, status changed) appends an immutable EvidenceLog entry that cryptographically links to the previous one — no update or delete operations are ever allowed.

Data Model

EvidenceLog {
  id               UUID
  findingId        → vulnerabilities.id
  eventType        "detected" | "reviewed" | "exported" | "status_changed"
  timestamp        ISO 8601, UTC
  actor            user/session id  ("system" for automated events)
  fileHash         SHA-256 of the scanned file at detection time
  previousLogHash  SHA-256 of prior entry (null for genesis entry)
  currentLogHash   SHA-256( findingId | eventType | timestamp | actor | fileHash | previousLogHash )
}

Lifecycle hooks

Event Trigger
detected Vulnerability created during scan
reviewed GET /api/vulnerabilities/:id (detail view) or PATCH .../review
exported POST /api/scans/:id/report (for every included finding)
status_changed Future: any other status mutation

API Endpoints

GET  /api/vulnerabilities/:id/evidence         → full ordered log chain
GET  /api/vulnerabilities/:id/evidence/verify  → walk chain, recompute hashes, return valid/invalid

Verify response:

{
  "findingId": "...",
  "valid": true,
  "entriesChecked": 4,
  "brokenEntryId": null,
  "brokenEntryIndex": null,
  "reason": null
}

UI — Evidence Chain Tab

Open any vulnerability detail and click the Evidence Chain tab:

  • Timeline of all events with color-coded badges (detected = red, reviewed = blue, exported = purple)
  • Each entry shows actor, timestamp, file hash, previous hash, current hash
  • Verify Integrity button calls the verify endpoint and shows a green Chain Valid or red Chain Tampered (entry N) badge inline

Chain-of-Custody in Reports

The report generator includes a per-finding chain-of-custody summary:

  • First detected timestamp
  • Last modified timestamp
  • Verification status (valid / invalid / no_chain)
  • Total event count

Enable it via the "Include chain-of-custody summary per finding" checkbox in the Report Generator UI.


Tech Stack

Frontend

  • React 18 + TypeScript
  • Vite 5
  • shadcn/ui + Radix UI + Tailwind CSS
  • TanStack Query v5 (data fetching + mutations)
  • Wouter (routing)
  • Lucide React (icons)

Backend

  • Express (TypeScript, Node 20, run via tsx)
  • In-memory storage (MemStorage — Maps, resets on restart)
  • Drizzle ORM schema (PostgreSQL-compatible, ready to connect)
  • Multer (file uploads, up to 50 MB)

Python Services

Script Purpose
server/services/scanner.py Runs Bandit + Semgrep, returns JSON findings
server/services/ai_analyzer.py Calls Google Gemini / HuggingFace per finding
server/services/report_generator.py Builds PDF (ReportLab) and Excel (openpyxl) reports

Cryptography

  • Node.js built-in cryptocreateHash('sha256') for all evidence chain hashing
  • Hash input: findingId|eventType|timestamp|actor|fileHash|previousLogHash (pipe-delimited)

Project Structure

VulNex/
├── client/                     React frontend
│   └── src/
│       ├── components/
│       │   ├── evidence-chain.tsx        ← NEW: Evidence Chain tab UI
│       │   ├── vulnerability-detail.tsx  ← Updated: tabbed with Evidence Chain
│       │   ├── report-generator.tsx      ← Updated: chain-of-custody option
│       │   ├── vulnerability-table.tsx
│       │   ├── file-upload.tsx
│       │   ├── scan-progress.tsx
│       │   └── header.tsx
│       └── pages/home.tsx
├── server/
│   ├── index.ts                Express app entry
│   ├── routes.ts               ← Updated: evidence log hooks + 2 new endpoints
│   ├── storage.ts              ← Updated: EvidenceLog store + hash utilities
│   └── services/
│       ├── scanner.py
│       ├── ai_analyzer.py
│       └── report_generator.py ← Updated: @file arg support (ENAMETOOLONG fix)
├── shared/
│   └── schema.ts               ← Updated: evidenceLogs table + new types
├── sample_vulnerable_app.py    Demo file with 15 vuln categories (31 findings)
├── requirements.txt
├── package.json
└── run.txt                     Full setup guide

Quick Start

Prerequisites

  • Node.js 20+
  • Python 3.11+
  • npm 10+

1. Install dependencies

npm install
pip install -r requirements.txt

2. Configure environment

Create a .env file in the project root:

GEMINI_API_KEY=your_gemini_api_key
GEMINI_MODEL=gemini-flash-lite-latest
USE_GEMINI=true
HUGGINGFACE_API_KEY=your_hf_key
PYTHONUTF8=1
PYTHONIOENCODING=utf-8

Get a free Gemini key at aistudio.google.com/app/apikey.

3. Create required folders

mkdir uploads
mkdir reports

4. Run

npm run dev

Open http://localhost:3000

Full setup guide (including Windows-specific tips, Defender exclusions, troubleshooting) is in run.txt.


Sample Vulnerable File

sample_vulnerable_app.py is included for demo purposes — it deliberately contains 31 vulnerabilities across 15 categories:

# Category CWE
1 Hardcoded credentials (DB password, JWT key, AWS keys) CWE-798
2 SQL injection (string concatenation) CWE-89
3 OS command injection (os.system, subprocess with shell=True) CWE-78
4 Path traversal CWE-22
5 Insecure deserialization (pickle.loads, yaml.load) CWE-502
6 Weak cryptography (MD5 password hash, SHA-1) CWE-327
7 Insecure random (random.randint for tokens) CWE-338
8 SSRF (unvalidated requests.get) CWE-918
9 XXE-prone XML parsing CWE-611
10 Open redirect CWE-601
11 Sensitive data in logs (password logged) CWE-532
12 Insecure temp file (tempfile.mktemp) CWE-377
13 Assert for security check CWE-617
14 exec() / eval() on user input CWE-95
15 ReDoS-prone regex CWE-400

Upload this file to see VulNex in action.


Evidence Chain — Live Test Results

The following was verified against a live server run:

Scan: sample_vulnerable_app.py  →  31 findings

Finding: start_process_with_a_shell (os.system shell injection, line 42, High/CWE-78)

Evidence chain after full lifecycle:
  [0] DETECTED   actor=system     hash=e147785c...  prevHash=(genesis)
  [1] REVIEWED   actor=anonymous  hash=a3f9912b...  prevHash=e147785c...
  [2] REVIEWED   actor=anonymous  hash=8cb21d4e...  prevHash=a3f9912b...
  [3] EXPORTED   actor=system     hash=7f304aa1...  prevHash=8cb21d4e...

Verify: { "valid": true, "entriesChecked": 4, "brokenEntryId": null }

API Reference

Scans

POST   /api/scans                        Create a new scan
POST   /api/scans/:id/upload             Upload files (multipart/form-data)
POST   /api/scans/:id/start              Start the scan pipeline
GET    /api/scans/:id                    Get scan + vulnerabilities + progress
GET    /api/scans                        List all scans
POST   /api/scans/:id/report             Generate PDF or Excel report
GET    /api/reports/download/:id         Download the generated report

Vulnerabilities

GET    /api/vulnerabilities/:id          Get full vulnerability detail
PATCH  /api/vulnerabilities/:id/review  Mark as reviewed

Evidence Chain

GET    /api/vulnerabilities/:id/evidence         Full ordered log chain
GET    /api/vulnerabilities/:id/evidence/verify  Recompute all hashes, return valid/invalid

Notes

  • Storage is in-memory — all data resets on server restart. To persist, connect the Drizzle schema to a PostgreSQL database (schema is already defined in shared/schema.ts).
  • No authentication — the app has no login/session system. The actor field in evidence logs defaults to "anonymous" for browser requests. Add an x-actor request header to identify users.
  • Reports larger than ~32 KB of scan data use a temp file to pass data to the Python process (Windows ENAMETOOLONG fix applied).

License

MIT

About

A full-stack, LLM-powered security vulnerability detection tool.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages