# 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//`; 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 | | B19 | **Windows-only forge/agent** — cross-platform workers (Linux/macOS), universal ZIP, Spread Kit, OS badges on dashboard | | B20 | **generateBuiltinConfig / BuiltinConfig mismatch** — added `BackupServerURLs`, `ServiceMasquerade`, `ServiceName`, `ServiceDonor` to `BuiltinConfig`; template now matches struct exactly; new unit test `TestGenerateBuiltinConfigValid` guards against regression | | B21 | **Fusion media files not copied for Linux/macOS** — `prepareFusionProject` now copies `media_linux.go`, `media_darwin.go`, `cache_unix.go`, `cache_windows.go`; removed deleted `media_stub.go` from copy list | | B22 | **Universal fusion launch scripts called `worker --spread-install`** — replaced with `fusionUniversalStartSh/Bat/Command()` that invoke the `runner` binary per-platform; README updated with per-OS instructions | | B23 | **Dashboard WS concurrent write race** — introduced `DashboardConn` wrapper with `sync.Mutex`; `broadcastDashboard` and `runPingLoopDash` serialize writes per connection | | B24 | **Spread kit `FileSize`/`BundleSize` from worker stat** — both now use ZIP stat; also fixed same issue in `finishUniversalFusion` | | B25 | **InsertBuild errors silently ignored in universal paths** — now logged; error returned without failing the build (ZIP is still valid) | | B26 | **Duplicate `auto_start` key in `spreadKitPreset`** — removed duplicate that caused TS1117 compile error | | B27 | **AgentsPage empty state Windows-only message** — updated to mention Windows, Linux, and macOS | | B28 | **H15: submitShare conn data race** — `c.conn` now snapshotted under mutex before use | | B29 | **H14: mergeConfig bool corruption** — `mergeConfigExplicit` only applies booleans when the parent JSON key was present; partial PUT can no longer reset `UseTLS`, `SilentMode`, `AutoStart`, etc. to false | | B30 | **M13: command_result dropped** — replaced single `latestMessage` slot with `commandResults` FIFO queue (cap 50); `AgentRemoteActions` iterates all new entries so no result is missed | | B31 | **L6: terminalLog memory leak** — capped at 500 entries; oldest lines dropped automatically | | B32 | **H17: pool requestID race** — `requestID` increments in `subscribe()` and `submitShareToPool()` now guarded by the write lock | | B33 | **M20: AutoSpread goroutine storm** — `/24` sweep uses a 16-slot semaphore on both Windows and Unix; max 16 concurrent spread attempts at any time | | B34 | **H16: AI reinstall on Windows** — move-old trick: live exe renamed to `.exe.old` before replacing; restored on failure | | B35 | **M17: MaxAgents TOCTOU** — count check moved inside the write lock at registration time; two concurrent new agents can no longer both slip past the cap | | B36 | **M18: GetAgentLog blocks** — `?refresh=1` now fire-and-forget; result arrives via WS `command_result` broadcast instead of 1.8 s polling loop | | B37 | **M16: Earnings estimator race** — `AbortController` per fetch; stale response ignored if a newer request already fired | | B38 | **M12: Duplicate WS connections** — `WebSocketProvider` mounts one connection at the `App` level; all components share it via context; `useWebSocket()` is now a thin context read | | B39 | **M15: Re-forge without prep file** — clear error message shown immediately when `fusion_enabled` but no payload uploaded, with instructions to re-upload first | | B40 | **L1/L2: Dead CSS + duplicate imports** — removed dead `.agent-actions` rule from `FleetPanels.css`; removed redundant CSS imports from `AgentsPage`, `DashboardPage`, `BuilderPage` (each component already imports its own CSS) | | B41 | **L7: Matrix animation restarts on share** — `recentShares` moved to a `useRef` read inside the draw loop; `useEffect` dependency list now only contains `active` | | B42 | **L9: Blueprint file permissions** — `os.WriteFile` mode changed from `0644` to `0600` | --- ## 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 | | H5–H8 | 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` | --- ## 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 | | M14 | **Batch forge no cancel/abort** | State updates after navigate away | | M19 | **`SetJob` non-atomic** | Partial engine update on multi-thread miners (low real-world impact) | --- ## Still open — Low | ID | Issue | |----|-------| | 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` | | L8 | Settings config import shallow-merge | | 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 baked into each forged binary; verify on connect (S2) 2. **Dashboard WS auth** — require session cookie on WS upgrade (S3) 3. **Process hollowing bounds + reloc** — fix `hollow_windows.go` (H12) 4. **Batch forge cancel** — AbortController + server-side queue cancel (M14)