Repository: https://github.com/bristinWild/forumer @ b9907523bffc975723762f1766f483d576b677e3
When: 2026-10-28 07:37 UTC · Model: venice/deepseek-v4-1-flash-1017
Sandbox: container dressed as a laptop; the host kernel is not hidden.
The review hit its 150-minute limit and was stopped; what it found by then is below.
The reviewer hit the 150-minute limit before writing its report; it wrote it afterwards from its session (resumed by hand on 2026-10-28), testing nothing more.
Summary: Forumer's cryptographic core is sound: signed canonical posts with PoW/Ed25519/id re-verification, XChaCha20-Poly1305 for private wire/at-rest data, Argon2id vaults, encrypted account state/outbox, parameterised SQL and a bounded sync parser. The serious weaknesses are resource control and metadata privacy. Any author can attach four 96 KiB signed previews per post to an uncapped, never-runtime-pruned SQLite table (remote disk fill), and unsigned mprev/mhere messages grow in-memory maps without a budget. Private-forum posts are sealed at rest but their forum id, persona public key, timestamps and thread graph are stored in clear, so a local file reader learns who posts in which private forum. Holder hints also let a peer make the victim dial loopback/LAN/arbitrary addresses, and CI/release workflows use mutable action refs with a write token. Several smaller findings include unbounded vault KDF parameters, a wrong Markdown backslash assumption, log scrubbing gaps, weak forum-name Unicode validation, and store-page/digest/range work limits. 163/163 core tests passed under ASan/UBSan; the published .lgx QML matches the reviewed source, but the module itself could not be built without Nix/logos-module-builder.
| id | severity | finding | confirmed | where |
|---|---|---|---|---|
| FR-1 | High | Signed posts allow uncapped preview storage; previews are only pruned at startup | read | src/forumer_backend.cpp:2532-2593; lib/forumer_core/src/post_store.cpp:44-53,344-348; src/forumer_backend.cpp:450-457; src/forumer_backend.h:355; lib/forumer_core/include/forumer_core/media.h |
| FR-2 | Medium | Private-forum post metadata (forum id, persona key, timestamps, reply graph) is stored in clear | run | lib/forumer_core/src/post_store.cpp:24-42,248-260,44-53; lib/forumer_core/src/forums.cpp (sealStored seals only envelope) |
| FR-3 | Medium | Unsigned mprev/mhere messages grow in-memory maps without a budget | read | src/forumer_backend.h:526-550; src/forumer_backend.cpp:2317-2350,2378,2536 |
| FR-4 | Medium | Holder hints make the storage node dial attacker-chosen addresses, including loopback/LAN/UDP | read | lib/forumer_core/src/sync.cpp:83-105; src/forumer_backend.cpp:2377-2400,2398 |
| FR-5 | Medium | CI/release workflows use mutable action refs and a contents:write release job | read | .github/workflows/ci.yml:15-16,39-44; .github/workflows/release.yml:31,36,67; .github/workflows/e3-ui.yml:28,41; .github/workflows/e3-two-node-manual.yml:25,33; .github/workflows/windows-build.yml:17,25 |
| FR-6 | Low | Vault accepts unbounded Argon2id parameters from the vault file | run | lib/forumer_core/src/vault.cpp:73-84 |
| FR-7 | Low | Markdown sanitiser backslash assumption is wrong for Qt; limited raw HTML injection/text spoofing | run | src/qml/markdown.js:21-51,111-130; src/qml/MdText.qml:12-13 |
| FR-8 | Low | Log scrubbing misses full local paths, 16-char private forum ids and 10-char fingerprints | run | src/forumer_backend.cpp:433,458,3136,3189,3213,3236,819; lib/forumer_core/include/forumer_core/redact.h:22-40; src/forumer_backend.cpp:74-100 |
| FR-9 | Low | Private-forum names accept bidi/invisible/overlong UTF-8; display spoofing and a serialisation throw | run | lib/forumer_core/src/forums.cpp:40-60; lib/forumer_core/src/identity.cpp (AccountState::toJson); src/qml/links.js:66-73; src/qml/Sidebar.qml |
| FR-10 | Low | Store-page parser has no message/size/cursor limits and wraps statusCode | read | src/delivery_module_transport.cpp:112-155; src/forumer_backend.cpp:3793 |
| FR-11 | Low | Preview answers cross forum boundaries and leak private post ids | read | src/forumer_backend.cpp:2317-2370,2440-2465; lib/forumer_core/src/post_store.cpp:356-364 |
| FR-12 | Low | Post log rows are trusted on read and not integrity-protected | read | lib/forumer_core/src/post_store.cpp:24-42,248-275,286-300; src/forumer_backend.cpp (loadPost, emitPost, sendOwn) |
| FR-13 | Low | fetchAround multiplies an unchecked day before validating it (signed overflow) | read | src/forumer_backend.cpp (fetchAround, ~3567-3590) |
| FR-14 | Low | Display fingerprints are only 40 bits and grindable | read | lib/forumer_core/src/identity.cpp:52-68 |
| FR-15 | Low | Repository hygiene: committed development log and fixture-looking key | read | git history commit 3737669 file '-a'; scripts/test-links.mjs:36 |
| FR-16 | Low | Storage upload completion can be attributed to another app's upload | read | src/forumer_backend.cpp (storageUploadDone handler ~965-1010; pumpUploads ~1960-2010) |
| FR-17 | Low | Digest scans and empty range requests still perform per-message work | read | lib/forumer_core/src/digest_plan.cpp:10-45,56-75; src/forumer_backend.cpp (handleDigest, handleRange) |
| FR-18 | Low | readIndex/vault::open are not exception-safe on malformed local JSON | read | lib/forumer_core/src/account_store.cpp (readIndex ~112-132); lib/forumer_core/src/vault.cpp:60-85 |
| FR-19 | Low | A peer can forge outbox Sent confirmation | read | src/forumer_backend.cpp (confirmHeldByPeers, handleDigest) |
Full exploit and fix per finding in report.md.
The whole session in Basecamp, recorded in the sandbox.

































| model calls | 200 |
|---|---|
| input tokens | 42,817,195 (41,285,198 cached) |
| output tokens | 105,042 |
| model time | 1990.7 s |
| estimated cost | $0.8953 |
| provider errors | 0 (retries 2) |
Triage, not approval. Automated and imperfect; the environment was instrumented.