Files: src/forumer_backend.cpp:3275-3310 (checkPost), src/forumer_backend.cpp:3321-3395 (handlePost/inHistoryWindow), src/forumer_backend.cpp:3361-3372 (new-key budget skipped when inHistoryWindow), lib/forumer_core/src/flood.h layers 2-3.
Exploit: handlePost uses one predicate for both the arrival limit and the new-key budget:
const bool inHistoryWindow =
m_storeImport || (m_historyActive && ts >= m_historyFrom && ts < m_historyTo);
const std::string problem = checkPost(post, inHistoryWindow);
...
if (!inHistoryWindow && !m_posts->hasAuthor(post.publicKey)) {
// new-key / priority token buckets
}
With fromHistory=true, checkPost skips countByAuthorArrival (the live anti-backdating limit) and only checks the per-key daily cap, counted over the author's own [ts-24h, ts]. The new-key budget is also skipped. A peer can read the unencrypted range request ({"v":1,"t":"range","since":…,"until":…}) that the victim publishes on the public topic, then send posts timestamped inside that [since,until) window. Each post is signed by a fresh key, so the per-key caps never bind; only 16-bit PoW per post is paid. The probe probes-review/p_history_flood.cpp (rules replicated against the real PostStore/flood/post libraries) offers 45 such posts spaced 30 h apart in a witnessed 90-day window:
posts offered in the witnessed history window: 45
accepted by the history-path rules: 45
rejected: 0
of the accepted, refused three-per-minute-ish by the new-key budget
if they had come in live: 45 (skipped on this path)
stored rows: 45
The same predicate makes any message returned by a store node (m_storeImport) bypass both budgets; the store fleet is remote and can be compromised or spoofed on-path.
Fix: Do not skip the new-key budget or per-arrival limit for history/store posts. Add a separate bounded history-import rate (e.g. tokens per minute and a byte budget) and apply the same arrival clock; cap the number of posts accepted per range/store page per peer; validate that history posts are actually in a range we requested from a peer/store we asked.