Fingerprint via weak-chain block submission #2757

issue jgarzik opened this issue on June 10, 2013
  1. jgarzik commented at 8:14 PM on June 10, 2013: contributor

    A node may be fingerprinted by submitting a unique block to that node, in a weak chain, and then later requesting it. Usually the attack involves submitting a low-PoW block at 2009-era height to an active, up-to-date node.

    Solution: do not serve never-in-the-best-chain blocks, or a similar solution.

  2. ashleyholman commented at 8:14 AM on August 12, 2013: contributor

    Hi Jeff,

    I am interested in trying to help with the bitcoin project, and this issue looks like an interesting one to start with since it is a privacy issue that would be good to fix. If I were to work on a patch, should I post it here for review?

    Thanks Ash

  3. ashleyholman commented at 11:08 AM on August 13, 2013: contributor

    Just a note to say that I've had a chat with @gmaxwell and he's given me some pointers on how I can get started with reproducing this as a test case. This will take me a while to get familiar with the various testing tools, but I'll post back here once I've got a test case.

  4. ashleyholman commented at 6:05 AM on August 17, 2013: contributor

    I have done some investigation and testing of this issue and here are my findings:

    • The minimum work required to fingerprint a node is based on the GetLastCheckpoint() block, by calculating ComputeMinWork() on that block and factoring in the maximum difficulty drops possible in the time elapsed since that checkpoint. Hence, the difficulty of generating a fingerprint drops by a factor of 4 every 2 weeks, until a new checkpoint is put in place.
    • A node that is doing an initial sync and is prior to the checkpoint at 168000, will accept a minimum difficulty block, so can be easily fingerprinted. In the future, more checkpoints will drop to minimum difficulty (eg. 3 weeks from now, the 168000 checkpoint will also be minimum difficulty).
    • Once fingerprinted, a node will always return the block when requested, even if they are fully up to date on the latest chain. Therefore an attacker will always be able to identify the fingerprinted user, even after initial sync.
    • In order to fingerprint a fully up to date node, by my calculations would require a difficulty 68248 block (at time of writing). This will get 4x easier every 2 weeks. At current network difficulty, that amount of work is worth ~0.033BTC. So, it is easily viable for anyone to fingerprint an up-to-date node today, but it is perhaps not so viable to do large-scale tracking of users since this would cost ~$3.50 per user.

    To test this I made a fingerprinting script which sends a difficulty-1 block. As mentioned, the script will work on nodes prior to checkpoint 168000, but for more up-to-date nodes you would need to generate a block with more proof-of-work. My code is here: https://gist.github.com/ashleyholman/6255449

    Perhaps one solution to protect against this, would be to never serve blocks that are at a height prior to the last checkpoint and not in the main chain. Any economically viable attempt at fingerprinting will use a block that's at a height well below recent checkpoints, so this should serve as good protection.

    If someone can respond here and suggest a way forward for fixing this, I would be happy to work on a patch.

    Thanks

  5. sipa commented at 9:04 AM on August 17, 2013: member

    Does anyone see a problem with just ignoring requests for blocks that are not in the main chain, unless they are very recent?

  6. gmaxwell commented at 10:36 AM on August 17, 2013: contributor

    @sipa The only problem I see is that it could make life harder for a fancy pruned node trying to reorg off a side chain. Limiting it to very recent (/during this runtime) / blocks that were in our best chain previously shouldn't break that too awfully at least.

  7. ashleyholman commented at 1:32 PM on August 19, 2013: contributor

    I have issued a pull request with a proposed patch. The fix is along the lines that were discussed here, except it is erring on the conservative side, in that I interpreted "recent" to mean "since last checkpoint". The behaviour doesn't change for any blocks that come after the last checkpoint. This still makes it far less feasible to do fingerprinting:

    • Minimum difficulty to fingerprint, based on last checkpoint, would be 4.3 million (~2.1 BTC per fingerprint)
    • The difficulty of fingerprinting would remain constant rather than dropping every 2 weeks
    • Each time the client is updated with new checkpoints, old fingerprints will stop working
  8. rebroad commented at 12:44 AM on March 6, 2014: contributor

    I think this can be closed now, can't it? (since it's now merged into master).

  9. laanwj commented at 12:25 PM on March 6, 2014: member

    Yep Thanks for solving this @ashleyholman

  10. laanwj closed this on Mar 6, 2014

  11. Bushstar referenced this in commit 588eb30b86 on Apr 5, 2019
  12. MarcoFalke locked this on Sep 8, 2021

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-04-20 00:16 UTC

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