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.
9.5 KiB
9.5 KiB
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.
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 |
| 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:
test.bat
Or manually:
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 for phase breakdown and E2E options.
Priority for next pass
- Agent WS token auth — bind
agent_idto build secret baked into each forged binary; verify on connect (S2) - Dashboard WS auth — require session cookie on WS upgrade (S3)
- Process hollowing bounds + reloc — fix
hollow_windows.go(H12) - Batch forge cancel — AbortController + server-side queue cancel (M14)