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

5.1 KiB

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