From b9fdc79818cef8a0eca123da986506cffc6ac0ec Mon Sep 17 00:00:00 2001 From: DanS Date: Mon, 13 Jul 2026 16:06:39 -0500 Subject: [PATCH] fix(net): verify PoW at header-accept once synced (header-flood DoS) AcceptBlockHeader called CheckBlockHeader with fCheckPOW=0, so a synced node stored any well-formed PoW-less header off the tip into mapBlockIndex without bound (memory/disk DoS). nMinimumChainWork is defined but unenforced and would not stop tip-siblings anyway (they inherit the tip's chain work). Verify PoW at header-accept time when not in IBD: forged headers now fail RandomX and the peer is DoS-banned. IBD keeps fCheckPOW=0 for fast header sync; the full-block RandomX/target check at connect is unchanged, so no valid header is rejected (not a consensus-rule change). fCheckPOW=0 call site is Leto (6a30b40415). Co-Authored-By: Claude Opus 4.8 --- src/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 12b405a95..e8884b3bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5443,7 +5443,10 @@ bool AcceptBlockHeader(int32_t *futureblockp,const CBlockHeader& block, CValidat } return true; } - if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state,0)) { + // SECURITY (header-flood DoS): once synced, verify PoW at header-accept time so a peer cannot + // flood unbounded PoW-less headers into mapBlockIndex (they now fail RandomX -> DoS-ban). During + // IBD keep fCheckPOW=0 for fast header sync; the full RandomX/target check runs at block connect. + if (!CheckBlockHeader(futureblockp,*ppindex!=0?(*ppindex)->GetHeight():0,*ppindex, block, state, IsInitialBlockDownload() ? 0 : 1)) { if ( *futureblockp == 0 ) { LogPrintf("%s: CheckBlockHeader futureblock=0\n", __func__); return false;