11 KiB
11 KiB
Problems
Findings from systematic bug-hunt and test expansion (May 2026).
Verification: test.bat from project root, or go test ./... in server/agent and npm test in server/web. AI handler only: cd server && go test ./internal/api/... -run AI -v.
Open
Critical / security
- [CRITICAL] server/internal/api/router.go — Unauthenticated build downloads (
/api/v1/builds/{id}/download,/artifact/). Intentional for agent reinstall (UUID is secret). Suggested fix: optional auth toggle or short-lived signed URLs. - [CRITICAL] server/internal/api/websocket.go — Unauthenticated agent WebSocket (
/ws/agent); any client can claim anyagent_id. Suggested fix: bindagent_idto fleet secret baked into forged binary (S2 from prior audit). - [CRITICAL] server/internal/api/websocket.go — Unauthenticated dashboard WebSocket (
/ws/dashboard); full fleet telemetry without login. Suggested fix: require Basic auth or session cookie on WS upgrade. - [CRITICAL] server/internal/api/ai_handler.go — Unauthenticated AI endpoints (
/agent/decide,/report,/heartbeat); SSRF via caller-supplied Ollama URL. Suggested fix: require fleet secret or dashboard auth. - [HIGH] server/internal/api/router.go — Plaintext passwords in
users.json; any authed user can POST/users. Suggested fix: bcrypt-only storage (partially done), restrict user management to admin role. - [HIGH] server/internal/api/fleet_handler.go — Remote code execution via authenticated API (
powershell/exec/upload). By design — treat dashboard login as root.
High
- [HIGH] server/internal/api/fleet_handler.go —
upload_logreturns content in tool report only; no dedicated log ingest API. - [HIGH] agent/ —
AutoSpreadruns when bakedtruein forge; dangerous if enabled on non-owned fleets. - [HIGH] agent/ — Process hollowing with
-tags hollow+ forge flag; bounds/reloc issues inhollow_windows.go.
Medium / UX
- [MEDIUM] server/web — Compact agent list default; expand on click.
- [MEDIUM] server/web — Remote actions disabled unless
online(by design). - [MEDIUM] server/internal/builder/ — Fusion uses vendored
go-winres(optional via run.bat). - [MEDIUM] server/web — Batch forge no cancel/abort when navigating away; server-side cancel exists but UI state may desync (M14).
- [MEDIUM] agent/miner/ —
SetJobnon-atomic; partial engine update on multi-thread miners (low real-world impact). - [MEDIUM] server/internal/db/sqlite.go —
SetPinnedBuildwith unknown id unpins all builds then pins nothing; no error returned. - [MEDIUM] server/web/src/pages/AgentsPage.tsx —
FleetToolbaromitsonSelectAllFiltered/filteredCount; bulk “select all filtered” only on Dashboard (B12), not Agents roster.
Low
- [LOW] server/internal/api/fleet_handler.go — Package-global
xmrPriceCacheshared across requests/tests; no per-server isolation if multiple routers in one process (unlikely in production). - [LOW] server/web/src/types/ws.ts + server/internal/api/ws_types.go — WS payloads typed in two places; drift risk.
- [LOW] tests/ — No integration tests for remote actions end-to-end.
- [LOW] agent/ — Mesh P2P requires build tag
p2p. - [LOW] server/config.go —
LoadConfiguses legacymergeConfig(notmergeConfigExplicit); a hand-editedconfig.jsonomitting bool fields can still zero them on restart. - [LOW] server/internal/api/config_handler.go —
ConfigHandler.dbis unused; handler delegates entirely toConfigProvider. - [LOW] server/main.go —
UpdateConfigFromJSONhas no semantic validation (negative ports, empty pool host, etc.); invalid values persist to disk. - [LOW] server/internal/db/agent_meta.go —
decodeTagssilently drops invalid JSON intagscolumn (corrupt values become empty slice). - [LOW] server/web/e2e/smoke.spec.ts — E2E login still uses hardcoded
drjones/czapiewski; fails against first-run randomadminpassword. Suggested fix: seedusers.jsonin E2E fixture or read creds from env. - [LOW] server/web/src/types/index.ts — Interfaces only; no runtime type guards for API JSON (validation ad hoc in components).
- [LOW] server/web/src/pages/AgentsPage.test.tsx — Vitest stderr
ECONNREFUSED :3000when detail panel mountsAgentRemoteActions; tests pass but component may hit live fetch — mock in follow-up. - [LOW] server/web/src/pages/SettingsPage.tsx — Calibrate UI lives here (
/settingsroute); no separateCalibratePage.tsx. Form labels lackhtmlFor— a11y follow-up. - [LOW] server/internal/maintenance/retention.go —
os.RemoveAllerrors ignored; failed disk cleanup is silent. - [LOW] server/internal/maintenance/retention.go — Artifact dir removed before
DeleteBuild; if DB delete fails, build row remains without files on disk. - [LOW] server/internal/maintenance/retention.go —
StartRetentionJobsgoroutine has no shutdown hook (acceptable for server process lifetime).
Untested packages (next coverage targets)
- [LOW] server/internal/models/ — No unit tests.
- [LOW] server/internal/ollama/ — No unit tests.
- [LOW] server/internal/sys/ — No unit tests.
- [LOW] server/web/src/help/buildManager.ts, cheatSheetContent.ts — No unit tests yet.
- [LOW] server/web/src/components/ — Fleet panels, forge form, WebSocket provider — no vitest coverage yet.
Fixed (this session)
- server/web/src/pages/BuilderPage.tsx — Load failure no longer stuck on “Loading forge defaults…” when
formis null; error message shown instead. Wallet placeholder/short-wallet hint aligned to 90–106 chars. ExportedformatByteshelper. - server/web/src/pages/SettingsPage.tsx — Wallet placeholder aligned to 90–106 chars. Exported
deepMergehelper (config import). - server/web/src/pages/ — Added
BuilderPage.test.tsx(13) andSettingsPage.test.tsx(11, Calibrate UI at/settings). Page suite now 4 files / 46 tests. - server/web/src/test/fixtures.ts — Added
mockServerConfig()for page/API tests. - server/internal/api/config_handler.go — PUT errors return valid JSON;
invalid config:maps to HTTP 400; GET sets explicit 200. - server/config.go —
mergeConfigExplicittracks nested key presence; partial PUT{"server":{"dashboard_subtitle":"x"}}no longer resets sibling booleans (H14 nested shallow-merge). - server/internal/api/config_handler_test.go — 10 handler unit tests (GET/PUT, 405, invalid JSON, 400/500 paths, JSON escaping).
- server/config_test.go — 9
mergeConfigExplicitregression tests (partial PUT, nested merge, defaults, bool false, fallback). - server/internal/maintenance/ — Added
retention_test.go(12 tests):StartRetentionJobsno-op/disabled, immediate run, 6h tick interval, stats/build purge via temp sqlite + filesystem, zero-retention skips, closed-DB error logs, combined stats+builds pass. Coverage ~97%. ExportedretentionTickInterval+runRetentionFnhooks for testability only. - server/web/src/pages/AgentsPage.tsx — Bulk command errors now alert user (parity with Dashboard B13).
- server/web/src/pages/DashboardPage.tsx — Share log table uses composite React key when
share.idabsent; exportedformatShareTimehelper. - server/web/src/pages/AgentsPage.tsx —
listAgentsno longer overwrites live WS agent list when socket already connected (isConnectedRefguard). - server/web/src/pages/ — Added
DashboardPage.test.tsx(11) andAgentsPage.test.tsx(11); vitest config extended for.tsx+@testing-library/react. - server/internal/db/retention.go —
ListBuildsOlderThanused a partial column list; now usesbuildSelectCols+scanBuildfor consistent fullBuildRecordfields. - server/internal/api/integration_test.go — Integration tests used stale hardcoded
drjones/czapiewskicredentials; server now generates randomadminpassword on first run. Tests seed deterministicusers.jsonbefore router init. - server/web/src/help/fleetAnalytics.ts —
contributionBarsincluded offline agents in total hashrate denominator, skewing contribution percentages on the dashboard. - server/web/src/pages/SettingsPage.tsx — Access Control help text still referenced removed default credentials; updated to describe first-run console password.
- server/internal/api/ai_handler_test.go — Expanded unit tests for
HandleDecide,HandleReport,HandleHeartbeat, engine lifecycle, numeric constants (1000 report cap, 60s heartbeat, 120-char reasoning truncate), Ollama-failure sleep fallback, event broadcaster,recordActivitymerge. - server/internal/api/fleet_handler_test.go — Unit tests for all exported
FleetHandlermethods (GetAlerts,GetPoolStatus,GetAIActivity,GetXMRPrice,GetEarnings/GetEarningsEstimate,GetAgentLog,PostAgentCommand,PutAgentMeta,PostBulkCommand),EstimateXMRPerDay/parseFloatQuery, earnings/XMR price cache TTLs, SupportXMR field normalization, HTTP error branches (503/502/400), and WS command paths via mock transport + test agent WS. - server/web/src/help/forgeCompatibility.ts — Wallet preflight message said length 95–106 but validator accepts 90–106; message aligned with
looksLikeXMRWallet(). - server/web/src/help/ — Added/expanded vitest coverage:
forgeCompatibility.test.ts(37),forgeRules.test.ts(46),settingHelp.test.ts(8). - server/web/src/types/index.test.ts — Structural fixture tests for all major exported interfaces (20 tests); documents no runtime type guards.
Fixed (earlier passes)
See git history and prior audit IDs (B1–B42, C1–C6, H1–H8, etc.) in README / tests/README.md.
Recommended next section
- server/web/src/components/ — Fleet panels, forge form, WebSocket provider; mock
AgentRemoteActionsfetch in AgentsPage tests - server/web/src/help/buildManager.ts, cheatSheetContent.ts — remaining untested help modules
- server/web/e2e/smoke.spec.ts — seed first-run admin creds for E2E
- server/internal/models/ — struct/JSON round-trip tests
- Agent WS token auth (S2) — security hardening
Test run snapshot (this session)
| Suite | Result |
|---|---|
server Go tests |
PASS (all packages) |
server/internal/api -run Config |
PASS (13 tests) |
server -run Config|Merge |
PASS (13 tests) |
server/internal/api -run AI |
PASS (17 tests) |
server/internal/api -run Fleet |
PASS (39 tests) |
agent Go tests |
PASS |
server/web vitest (page tests) |
PASS — 4 files, 46 tests |
server/web vitest (full suite) |
PASS — 19 files, 206 tests |