Zero-latency reverse proxy · AST-aware code mapping · Local AI audit · No cloud required
Traditional WAFs match against static signatures—regex lists, known CVE patterns, OWASP rule sets. They have no idea what your code actually does. A request that looks benign might exploit a quirk in your specific login() implementation. A request that looks malicious might be perfectly safe because your code already sanitises it.
GhostCheck flips the model. It reads the live HTTP request and the source code that will handle it, then asks an LLM: "given this exact function, can this exact payload cause harm?"
┌─────────────────────────────────────────────────────────────┐
│ G H O S T C H E C K │
│ │
HTTP request │ ┌────────────────┐ Unix Socket ┌────────────────┐ │
────────────────▶ │ │ │ ─────────────▶ │ │ │
│ │ Wraith Proxy │ JSON stream │ Specter Agent │ │
HTTP response │ │ (Go) │ │ (Python) │ │
◀──────────────── │ │ │ │ │ │
│ └───────┬────────┘ └───┬────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Your Backend Tree-sitter Ollama │
│ (untouched) AST parse LLM audit │
│ │
└─────────────────────────────────────────────────────────────┘
|
The invisible layer. Wraith is a production-grade reverse proxy that sits in front of your application. Every request passes through unchanged—zero tampering, zero added latency to the response. Behind the scenes, it clones each request (method, path, headers, body, client IP) and streams a structured JSON event over a Unix domain socket to Specter. If Specter is down, Wraith stays up. Blind mode — logged, not blocked. |
The thinking layer. Specter receives the event stream and runs a multi-stage pipeline:
|
wraith-proxy/
├── main.go Reverse proxy server with production timeouts
├── interceptor.go Clones request body, builds InterceptEvent, pushes to socket
├── socket_client.go Singleton Unix socket client with thread-safe writes + auto-reconnect
└── go.mod
specter-agent/
├── main.py Unix socket server, event loop, dispatch
├── analyzer/
│ ├── mapper.py Route → source file resolution + Tree-sitter function extraction
│ └── tree_sitter.py C/C++ parser via tree-sitter-language-pack
└── brain/
├── langgraph.py Multi-stage audit engine (heuristic → mapping → LLM verdict)
└── llm_client.py LangChain + Ollama interface
shared/
└── ghostcheck.sock Unix domain socket (created at runtime)
Prerequisites — Go 1.22+ · Python 3.12+ · Ollama running locally
git clone https://github.com/your-username/ghostCheck.git
cd ghostCheck
mkdir -p sharedcd specter-agent
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python main.py
# 👻 Specter Agent: Listening on .../shared/ghostcheck.sock...cd wraith-proxy
go build -o wraith .
./wraith -target http://localhost:8080 -port 9000
# 🛡️ GhostCheck Production Proxy Started
# Listening on :9000 | Protecting: http://localhost:8080# Normal request — passes through
curl http://localhost:9000/api/login \
-d '{"user":"alice","pass":"secret"}'
# Suspicious request — Specter flags it
curl http://localhost:9000/api/login \
-d '{"user":"admin\" OR 1=1 --","pass":"x"}'| Variable | Default | Description |
|---|---|---|
GHOSTCHECK_SOURCE_ROOT |
tests/vulnerable_app/ |
Root directory containing the source files mapped by route |
OLLAMA_MODEL |
llama3.2 |
Which Ollama model to use for the security audit |
Routes are mapped to source files in specter-agent/analyzer/mapper.py:
PATH_TO_FILE = {
"/api/login": "login.cpp",
}Add entries as you expand coverage. Specter uses Tree-sitter to extract only the relevant function—the LLM never sees your whole codebase.
|
Injection Types
|
Analysis Depth
|
Verdict Format {
"action": "BLOCK",
"risk": "HIGH",
"reason": "unsafe system() call",
"evidence": "login.cpp: system(cmd)"
} |
| Principle | How |
|---|---|
| Zero interference | The proxy never modifies requests or responses. Your app behaves identically with or without GhostCheck. |
| Fail-safe | If the agent or LLM is unavailable, traffic flows normally. No single point of failure. |
| Local-first | All inference runs on your machine via Ollama. No API keys, no data leaving your network. |
| Code-aware | Decisions are grounded in the actual implementation, not generic vulnerability databases. |
| Minimal surface | Tree-sitter extracts only the target function. The LLM sees the smallest context needed. |
| Layer | Technology | Purpose |
|---|---|---|
| Proxy | Go net/http/httputil |
High-throughput reverse proxy with production timeouts |
| IPC | Unix Domain Socket | Near-zero-latency bridge between Go and Python |
| Parsing | Tree-sitter | Language-agnostic AST parsing for C/C++ function extraction |
| Reasoning | LangChain + Ollama | Local LLM inference with structured prompt engineering |
| Orchestration | LangGraph-style state machine | Heuristic → mapping → LLM → verdict pipeline |
╔══════════════════════════════════════════════════════╗
║ ║
║ It's not about blocking everything. ║
║ It's about understanding what your code can't ║
║ handle — before an attacker figures it out. ║
║ ║
╚══════════════════════════════════════════════════════╝
Built with paranoia. Runs with calm.
Made by kshitijmishra