signet: disk-space-DoS due to low mining difficulty #33266

issue 0xB10C openend this issue on August 28, 2025
  1. 0xB10C commented at 12:38 pm on August 28, 2025: contributor

    Due to low mining difficulty on Signet, an attacker can grind all possible nonces of a block header and create valid1, alternative headers for Signet blocks. Since these have the same chain work as the tip, the newly mined headers can be submitted along with the original block content via an unsolicited block P2P message. Nodes that don’t prune will store these blocks indefinitely.

    When initially reported in April 2025, on average 13208298 work (hash attempts) were required to find a valid nonce on the default Signet. Now, after the difficulty on Signet was increased2, recent signet blocks require 209338421 work on average. This results in 2^32 / 13208298 = ~325 valid headers for each block on average in April and 2^32 / 209338421 = ~20 valid headers for each block at the current Signet difficulty. An attacker can use this to fill up the disk of a Signet node.

    Assuming 144 Signet blocks per day and assuming a size of 500kB3 per block, the signet disk usage increases by about 72 MB per day. An attack could have resulted in a disk-usage increase of 325 * 72 MB = 23.4 GB per day in April. With the current difficulty, it could result in a disk-usage increase of 20 * 72 MB = 1.44 GB per day.

    A modern laptop can grind the full 2^32 nonce space in less than 30 seconds and an attacker only needs to store the nonces to build and publish the alternative blocks. This makes the attack fairly trivial to exploit.

    Credit goes to @stwenhao for initially reporting this in a fork-observer issue. The attack can be detected via getchaintips and e.g. tools like fork-observer. The alternative blocks show up as valid-headers. No reorg happens as the original block remains the active tip (since it was seen first).

    The attack is possible on all networks that require less than 2^32 work to find blocks. Pruned nodes are not affected as the alternative blocks are removed at some point. I’m opening this issue is to document this somewhere visible. I don’t think there’s action required for the default Signet at this point since the difficulty has already been increased and the attack is less effective there now. If this becomes a problem again, the best mitigation is probably to further increase the difficulty. Other public signets (e.g. Mutinynet) might want to consider increasing the mining difficulty too.


    1. Signet blocks commit to the header version, prevhash, merkleroot, and timestamp. These can’t be changed. Only the nonce can be changed to produce valid, alternative headers. ↩︎

    2. The Signet difficulty was increased at the end of April 2025 in response to a private report. ↩︎

    3. filling Signet blocks with transactions is possible for free, but blocks seem to be limited to 1 MWU. Consistently making 500 kB blocks seems to be possible for an attacker ↩︎

  2. bitcoin deleted a comment on Aug 29, 2025
  3. jsarenik commented at 12:31 pm on August 29, 2025: none

    Would such blocks mined by anyone even be considered valid on signet since they would not contain any expected valid signature?

    On signet there’s an “Additional consensus requirement that the coinbase witness commitment contains an extended signet commitment, which is a script satisfying the block script (usually a k-of-n multisig)” (see bitcoin.it documentation on Signet Differences). Maybe the in-repo documentation is not clear?

  4. 0xB10C commented at 5:42 pm on August 29, 2025: contributor

    Would such blocks mined by anyone even be considered valid on signet since they would not contain any expected valid signature?

    Yes. Just the nonce in the block header changes. The signet commitment commits to the header version, prevhash, merkleroot, and timestamp. It does not commit (and can not commit) to the nonce. The underlying block does not change. The commitment remains valid.

  5. stwenhao commented at 8:51 pm on August 30, 2025: none

    It does not commit (and can not commit) to the nonce.

    I agree, that it does not commit to the nonce. But if that would be needed, then it could. An example of a situation, where things are signed, but where nonce is included in signed commitment, is what I deployed as a Proof of Work puzzle: https://bitcointalk.org/index.php?topic=5551080.0

    Or, a similar case is recently deployed Optional Hourglass: https://bitcointalk.org/index.php?topic=5557305.0

    In that cases, the signature can sign everything (for example, nSequence and nLockTime is signed, and both can be used as nonces during mining). And also, signatures can sign less things, by using different sighashes, for example here: https://mempool.space/tx/8349df0753e80cce322322f1b76789e1d0fd6693aed2f4de4e49576423081ae7

    So, I can imagine a perfectly valid Signet challenge, where the size of the signature will be restricted somehow, where it would use different sighashes, than SIGHASH_ALL, or where miners would grind DER signatures, instead of grinding regular 80-byte block headers.

    To sum up: the current design of Signet allows attacking, by changing nonces into different values. But that attack can be trivially stopped, just by making sure, that for a given signed header, there is only one nonce, meeting a given difficulty (which means always checking all 2^32 nonces for each submitted header).

    But, future signets can use a different model, where they could entirely avoid such problems, and work with much smaller difficulty. Imagine taking this signet challenge:

    01 <pubkeyAlice> <pubkeyBob> 2 OP_CHECKMULTISIG
    

    And turning it into this instead:

    0OP_SIZE 61 70 OP_WITHIN OP_VERIFY
    1OP_CODESEPARATOR
    21 <pubkeyAlice> <pubkeyBob> 2 OP_CHECKMULTISIG
    

    Of course, because the Script from signet challenge can change the signed transaction ID, this is incompatible with currently deployed network. However, I can imagine a soft-fork on top of signet, where signatures would be required to be smaller, than they are, and where Proof of Work will be counted, by checking the signature, rather than by checking the hash in the block header. And then, block headers could have even regtest difficulty, if consensus rules would still require grinding something else (that could commit to the block header nonce, and difficulty as well).

    Edit: Also, there are many possible trivial fixes. For example, if each nonce will be restricted by consensus rules to be less than 0x00010000, then it could work, and it would be trivial, to check all 2^16 values, instead of 2^32.

  6. jsarenik commented at 4:44 am on August 31, 2025: none

    What about a safety one-liner fix which would not allow new block to have the same blockheader (except nonce) than an already mined block? Such a local-node “soft-fork” would be possible even without telling anyone network-wise.

    An attack block could come only after a new unique mined&signed block header was announced.

  7. stwenhao commented at 5:01 am on August 31, 2025: none

    What about a safety one-liner fix which would not allow new block to have the same blockheader (except nonce) than an already mined block?

    As long as you know, which block was propagated first, then you can do that. But note that signet block producers can decide to build things on top of any block, including something, which was grinded by some attacker. If you see two or more blocks with different nonces, at the same height N, then you don’t know, what block number N+1 will sign (and also, it can sign all versions, and leave it up to the miners).

    Such a local-node “soft-fork” would be possible even without telling anyone network-wise.

    Yes, but if your node joined the network recently, then you don’t know, if the block you heard from someone is the earliest one, that was broadcasted. You only know that, if something was created on top of it. Which means, that there is always a risk to see a single block being reorged, if you pick it wrong.

    Edit: Also note, that the default signet challenge is 1-of-2 multisig. Which means, that you can have for example two different nodes, making signatures for two different public keys. Both nodes can be connected to the same network, but they don’t have to maintain a direct P2P connection. Which means, that if you have one signet miner, and another signet miner, and there are some attackers in the middle, then they can capture the real block, grind it (also with ASICs, because why not), and share different headers with different nodes.

  8. 0xB10C commented at 12:36 pm on September 5, 2025: contributor

    My impression is that just increasing the difficulty on a public Signet should be enough and would avoid this issue without needing a (signet only) (consensus) code change. It doesn’t even need to be difficulty 1 (i.e. 2^32 work) - similar to the default signet only requiring 5% of work at the risk of 19 alternative blocks per tip. The attack is easily detectable and if exploited over a long period of time, the signet admin can further increase the difficulty at any time. Alternatively, publishing new blocks in batches ensures an attacker doesn’t have enough time to mine alternatives for each tip.

    It probably needs some documentation though: Either run your public signet with a high enough difficulty or risk being disk-space DoSed by some script kiddy. After all, it’s only a test network.

    AFAIK, so far nobody else bothered to mine alternative blocks on the default signet and neither on Mutinynet where it is/was trivial to grow the chain by 100GB per day (https://github.com/MutinyWallet/mutiny-net/pull/4).

  9. stwenhao commented at 1:33 pm on September 5, 2025: none

    and would avoid this issue without needing a (signet only) (consensus) code change.

    Yes, but signet-only consensus code change can be beneficial. If your difficulty requires grinding 2^20 hashes, then I think nonce values should be masked, to make sure, that upper bits are set to zero. Then, if the difficulty will increase, the code can automatically raise that barrier, so that the nonce restrictions will be active only for difficulties requiring less than 2^32 hashes.

    Because if you need to grind for example 2^16 hashes, then it is more realistic, if your nonce is also masked with 0x0000ffff. After all, miners constantly check a lot of different block headers, and they tweak version bits, timestamps, or change merkle roots. Restricting the nonce would mimic that behaviour for signets.

  10. benthecarman commented at 2:21 pm on September 22, 2025: contributor
    @stwenhao i don’t think restricting the nonce adds any meaningful protection. The attacker can also use the merkle root as a nonce field because they do not need to actually include txs. If you limit the nonces, they can just change the merkle root until they find a block
  11. 0xB10C commented at 2:29 pm on September 22, 2025: contributor

    @stwenhao i don’t think restricting the nonce adds any meaningful protection. The attacker can also use the merkle root as a nonce field because they do not need to actually include txs. If you limit the nonces, they can just change the merkle root until they find a block

    The signet solution commits to the merkleroot. Changing it will produce invalid Signet blocks:

    https://github.com/bitcoin/bitcoin/blob/953544d0286ba35dd1b07fe1921c573cba4703cf/src/signet.cpp#L112-L117

  12. jsarenik commented at 11:32 am on December 19, 2025: none

    Does this issue relate at all to the fixed CVE-2025-54604 - Disk filling from spoofed self connections in #32604 ?

    https://bitcoincore.org/en/2025/10/24/disclose-cve-2025-54604/

  13. maflcko commented at 11:51 am on December 19, 2025: member

    Does this issue relate at all to the fixed CVE-2025-54604 - Disk filling from spoofed self connections in #32604 ?

    https://bitcoincore.org/en/2025/10/24/disclose-cve-2025-54604/

    I think the two are separate:

    • One is about rate limiting all logs, so that the persisted debug.log file does not grow in size too fast.
    • This one is about creating and persisting blocks to the block*.dat files, and how it can be worked around by a higher difficulty.
  14. willcl-ark added the label Bug on Jan 14, 2026
  15. willcl-ark added the label Resource usage on Jan 14, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-21 09:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me