Files
AetherForge/PROBLEMS.md
drjones 0f9e04f5f6 Add universal forge, fusion disguise, remote deploy, and stability fixes.
Ship cross-platform spread kits and fusion ZIPs with per-OS launchers, one-liner dropper endpoints, Windows file disguise, and a large batch of wiring/bug fixes so agents connect reliably across a LAN test fleet.
2026-05-29 20:53:13 -07:00

158 lines
9.5 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 |
| 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 |
| 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` |
---
## 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)