Files
ThreatHunt/docs/update.md
2026-02-19 15:42:20 -05:00

137 lines
5.1 KiB
Markdown

# ThreatHunt — Session Update (February 19, 2026)
## Summary
This session covered 6 feature improvements and bug fixes across the ThreatHunt platform, all deployed via Docker Compose.
---
## 1. Network Map — Clickable Type Filters (IP / Host / Domain / URL)
**Request:** "IP, Host, Domain, URL on the network map… can I click on these and they would be filtered in or out"
**Changes (`NetworkMap.tsx`):**
- Legend chips (IP, Host, Domain, URL) are now clickable toggle filters
- Added `visibleTypes` state (`Set<NodeType>`) and `filteredGraph` useMemo that filters nodes + edges by visible types
- Active chips: filled background with type color, fully opaque
- Inactive chips: outlined with type color, dimmed at 50% opacity
- Each chip shows node count for that type, e.g. `IP (42)`
- At least one type must stay visible (can't disable all four)
- Stats chips (nodes/edges) update to reflect the filtered view
- All mouse handlers (pan, hover, click, wheel zoom) updated to use `filteredGraph` instead of raw `graph`
---
## 2. Network Map — Cleaner Nodes (Brighter Colors, 20% Smaller)
**Request:** "Clean up the icons, the colours are dull and the icons are too big in the map… shrink by 20%"
**Changes (`NetworkMap.tsx`):**
- Colors bumped to more saturated variants:
- IP: `#60a5fa``#3b82f6`
- Host: `#10b981``#22c55e`
- Domain: `#f59e0b``#eab308`
- URL: `#a78bfa``#8b5cf6`
- Node radius shrunk ~20%:
- Max: 22 → 18
- Base: 5 → 4
- Multiplier: 2.0 → 1.6
---
## 3. Dataset Viewer — IOC Column Highlighting
**Request:** "I'm looking at one of the datasets and 4 IOCs are showing… but I can't see it… is there a way to highlight that"
**Changes (`DatasetViewer.tsx`):**
- IOC columns in the DataGrid are now visually highlighted
- **Header:** colored background tint + bold colored text + IOC type label (e.g. `src_ip ◆ IP`)
- **Cells:** subtle colored background + left border stripe
- Color-coded by IOC type matching the Network Map palette:
- IP — blue (`#3b82f6`)
- Hostname — green (`#22c55e`)
- Domain — amber (`#eab308`)
- URL — purple (`#8b5cf6`)
- Hashes (MD5/SHA1/SHA256) — rose (`#f43f5e`)
- Added `IOC_COLORS` mapping, `iocTypeFor()` helper, and dynamic `headerClassName`/`cellClassName` on DataGrid columns
- CSS-in-JS styles injected via DataGrid `sx` prop
---
## 4. AUP Scanner — "Social Media (Personal)" → "Social Media" Rename
**Request:** "On the AUP page there is Social Media (Personal) — can we remove personal, it's messing up with the formatting"
**Changes (`keyword_defaults.py`):**
- Default theme key renamed from `"Social Media (Personal)"` to `"Social Media"`
- Added rename migration in `seed_defaults()`: checks for old name in DB, if found renames via SQL UPDATE + commit before normal seeding
- Backend log confirmed: `Renamed AUP theme 'Social Media (Personal)' → 'Social Media'`
---
## 5. AUP Scanner — Hunt Dropdown (previous session, deployed)
- Replaced individual dataset checkboxes with a hunt selector dropdown
- Selecting a hunt auto-loads and selects all its datasets
- Shows dataset/row counts below the dropdown
---
## 6. Network Map — Hunt-Scoped Interactive Map (previous session, deployed)
- Hunt selector dropdown loads only that hunt's datasets
- Enriched nodes with hostname, IP, OS metadata
- Click-to-inspect MUI Popover showing node details
- Zoom (wheel + buttons) and pan (drag) with full viewport transform
- Force-directed layout with co-occurrence edges
---
## 7. Agent Assist — "Failed to Fetch" Diagnosis
**Request:** "AI assist failed: Error: Failed to fetch"
**Diagnosis:**
- Backend agent endpoint works correctly (tested via PowerShell `Invoke-RestMethod` through nginx proxy)
- Health endpoint healthy — both LLM nodes (Wile + Roadrunner) available
- Extra fields sent by frontend (`mode`, `hunt_id`, `conversation_id`) are accepted by Pydantic v2 (ignored, not rejected)
- "Failed to fetch" was a transient browser-level network error, not a backend issue
- Response time ~5s from LLM — within nginx 120s proxy timeout
- **Resolution:** Hard refresh (Ctrl+Shift+R) resolves the issue
---
## 8. Performance Fix — /api/hunts Timeout (previous session)
- Root cause: `Dataset.rows` relationship had `lazy="selectin"` causing SQLAlchemy to cascade-load every DatasetRow when listing hunts
- Fix: Changed `Dataset.rows` and `DatasetRow.annotations` to `lazy="noload"` in `backend/app/db/models.py`
- Result: Hunts endpoint returns instantly
---
## Files Modified This Session
| File | Change |
|------|--------|
| `frontend/src/components/NetworkMap.tsx` | Type filter toggles, brighter colors, smaller nodes |
| `frontend/src/components/DatasetViewer.tsx` | IOC column highlighting in DataGrid |
| `backend/app/services/keyword_defaults.py` | Theme rename + DB migration |
## Deployment
All changes built and deployed via Docker Compose:
```
docker compose build --no-cache frontend
docker compose up -d frontend
docker compose build --no-cache backend
docker compose up -d backend
```
## Git
Committed and pushed to GitHub (`main` branch):
```
92 files changed, 13050 insertions(+), 1097 deletions(-)
d0c9f88..9b98ab9 main -> main
```