Files
AetherForge/PROBLEMS.md
drjones e55f11a657 Add full test suite with unit, integration, and E2E smoke tests.
Introduce test.bat orchestrating Go/Vitest/Playwright phases, expand coverage across server, agent, and dashboard, and document in tests/README.md.
2026-05-29 10:04:52 -07:00

152 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AetherForge — Problem Audit
Findings grouped by severity. Updated after full bug-hunt pass (May 2026).
**Last verified:** run `test.bat` from project root (all phases) or see [tests/README.md](tests/README.md).
---
## Fixed (this pass)
| ID | Fix |
|----|-----|
| B1 | **Pool jobs stop after disconnect**`readLoop` now waits for reconnect instead of exiting; login tracked by `loginRequestID` not hardcoded `1` |
| B2 | **Fusion upload disk exhaustion**`io.LimitReader` + reject unknown upload size |
| B3 | **Artifact path traversal**`safePathUnderRoot()`; `export_dir` limited to `fusion-deliverables/<title>/`; build ID validated before serve |
| B4 | **Multipart forge without fusion**`prep_exe` only required when `fusion_enabled` |
| B5 | **Build succeeds when DB insert fails** — forge now fails if `InsertBuild` errors |
| B6 | **Query limit DoS** — stats/shares `limit` capped at 1000 |
| B7 | **SPA static `..` traversal** — blocked in router fallback |
| B8 | **React 18 + R3F v9 crash** — pinned `@react-three/fiber@8` / `drei@9` (blank black screen) |
| B9 | **SessionGate stale token on network error** — catch sets `authed=false` |
| B10 | **AgentsPage notes/tags wiped while typing** — drafts sync only on agent switch |
| B11 | **WS reconnect timer stacking** — clear timer + close existing socket before reconnect |
| B12 | **Dashboard bulk select limited to top 12** — “Select all filtered” in FleetToolbar |
| B13 | **Dashboard bulk errors silent** — catch + alert |
| B14 | **AI `restart_miner` missing `.exe`** — normalize image name for taskkill/stat/start |
| B15 | **AI reinstall `http.Get` no timeout** — uses `httpClient` |
| B16 | **Fusion `worker_first` blocked forever** — worker launches async; media runs immediately |
| B17 | **Agent empty `new_job`** — logs error and re-requests job |
| B18 | **Agent WS read deadline**`PongHandler` extends deadline on server ping |
---
## Fixed (earlier passes)
| ID | Fix |
|----|-----|
| C1 | `BroadcastServerLog` on `WSHub` |
| C2 | `EncodeToString` in agent download handler |
| C3 | `AgentRemoteActions` legacy props |
| C4 | `useWebSocket` `latestMessage` + Agents detail wiring |
| C5 | Agent handlers: `ps`, `netstat`, `users`, `software`, `screenshot` |
| C6 | `NewMeshNode(c)` in `NewAgentClient` |
| H1 | WS reconnect: only mark offline if closing conn is still active |
| H2 | WS pre-auth guard on agent message types |
| H3 | Share submit via async pool queue |
| H4 | Fleet broadcast `all` fails when zero agents connected |
| H5H8 | AI: build ID reinstall, uptime, sleep parse, decide HTTP/error field |
| H10 | Download uses `EncodeToString` |
| H13 | `run.bat` fails on frontend build error; kills stale server before bind |
| M3 | `stats_update` includes memory, uptime, shares |
| M5 | Removed blocking 800ms sleep in `GetAgentLog` |
| M8 | `GetEngine` lock pattern simplified |
| M10 | CORS: `AllowCredentials: false` with `AllowedOrigins: *` |
| M11 | Blueprint delete returns boolean `success` |
---
## Still open — Critical / security
| ID | Issue | Notes |
|----|-------|-------|
| S1 | **Unauthenticated build downloads** | `/api/v1/builds/{id}/download` and `/artifact/` bypass auth (intentional for agent reinstall — UUID is the secret) |
| S2 | **Unauthenticated agent WebSocket** | `/ws/agent` — any client can claim any `agent_id` |
| S3 | **Unauthenticated dashboard WebSocket** | `/ws/dashboard` — full fleet telemetry without login |
| S4 | **Unauthenticated AI endpoints** | `/api/v1/agent/decide`, `/report`, `/heartbeat` — SSRF via caller-supplied Ollama URL |
| S5 | **Default credentials in source** | `drjones` / `czapiewski` until `data/users.json` exists |
| S6 | **Plaintext passwords** | `users.json` stores cleartext; any authed user can POST `/users` |
| S7 | **Remote code execution via API** | Authenticated users can send `powershell`/`exec`/`upload` to any online agent — by design, treat as root |
---
## Still open — High
| ID | Issue | Notes |
|----|-------|-------|
| H9 | `upload_log` returns content in tool report only | No dedicated log ingest API |
| H11 | `AutoSpread` runs when baked `true` in forge | Feature-gated but dangerous if enabled |
| H12 | Process hollowing with `-tags hollow` + forge flag | Bounds/reloc issues in `hollow_windows.go` |
| H14 | **Partial config PUT corrupts bools** | `mergeConfig` overwrites `UseTLS`, logging flags, etc. with zero values |
| H15 | **Agent `conn` data race** | `submitShare` reads `c.conn` without mutex |
| H16 | **AI reinstall while running** | `os.Rename` fails on Windows when exe in use |
| H17 | **Pool `requestID` / write races** | Concurrent share submits can interleave Stratum lines |
| H18 | **WS concurrent writes** | Ping loop vs broadcast on same dashboard connections |
---
## Still open — Medium / UX
| ID | Issue | Notes |
|----|-------|-------|
| M1 | Compact agent list default | Expand on click |
| M6 | Remote actions disabled unless `online` | By design |
| M9 | Fusion uses vendored `go-winres` | Optional via run.bat |
| M12 | **Multiple `useWebSocket()` hooks** | Dashboard + Matrix overlay = duplicate connections |
| M13 | **`latestWsMessage` drops rapid results** | Only last message kept; command results can be lost |
| M14 | **Batch forge no cancel/abort** | State updates after navigate away |
| M15 | **Re-forge fusion without re-upload** | `reForgeFromBuild` needs prep file |
| M16 | **Earnings estimator race** | Stale API response can overwrite newer estimate |
| M17 | **`MaxAgents` TOCTOU** | Limit checked before lock on agent WS auth |
| M18 | **`GetAgentLog?refresh=1` blocks** | Up to ~1.8s synchronous sleep per request |
| M19 | **`SetJob` non-atomic** | Partial engine update on multi-thread miners |
| M20 | **Autospread goroutine storm** | Up to ~254 goroutines per /24 sweep |
---
## Still open — Low
| ID | Issue |
|----|-------|
| L1 | Dead CSS `.agent-actions` in `FleetPanels.css` |
| L2 | Duplicate CSS imports on Dashboard/Agents |
| L3 | WS payloads typed in two places (`types/ws.ts` + Go) |
| L4 | No integration tests for remote actions |
| L5 | Mesh P2P requires build tag `p2p` |
| L6 | `terminalLog` / `agentLogs` grow without bound |
| L7 | Matrix overlay restarts animation on every share |
| L8 | Settings config import shallow-merge |
| L9 | Blueprint files written mode `0644` |
| L10 | XOR media crypto — weak confidentiality by design |
---
## Verification
Run the full suite:
```bat
test.bat
```
Or manually:
```bat
cd server && go test ./... && go build .
cd ..\agent && go test ./... && go build .
cd ..\server\web && npm test && npm run build
run.bat
```
See **[tests/README.md](tests/README.md)** for phase breakdown and E2E options.
---
## Priority for next pass
1. Agent WS token auth (bind `agent_id` to build secret)
2. Dashboard WS auth (match REST Basic auth)
3. Config merge with pointer types / explicit fields
4. Shared WebSocket context (single connection app-wide)
5. Process hollowing bounds + reloc (`hollow_windows.go`)