Skip to content

Security: upgrade to v1.2.1 — earlier nodes accept spends without a signature #15

Description

@Bitflash-sh

Every release before v1.2.1 accepts a transaction that spends any output without a valid signature. If you run a node, upgrade it now: https://github.com/Bitflash-sh/bitflash/releases/latest

What was wrong

VerifySignature evaluated scriptSig and scriptPubKey as one concatenated script, and OP_RETURN was implemented as pc = pend — stop executing — rather than failing the script. EvalScript then returns CastToBool(stack.back()).

So a scriptSig of <OP_TRUE OP_RETURN> pushed 1, jumped past the entire scriptPubKey including OP_CHECKSIG, and the script was judged by the attacker's own pushed value. No signature, any output, any owner.

This is the Bitcoin 0.1.0 behaviour, fixed upstream in 0.3.5. This fork is derived from 0.1.0 and inherited it.

Also fixed in v1.2.1

  • Unbounded script opcodes. There were no element-size, stack-depth or opcode-count limits. OP_CAT grows a stack element without a ceiling (<x> OP_DUP OP_CAT repeated doubles it each time) and OP_LSHIFT shifts by an attacker-supplied amount — either one lets a transaction small enough to relay exhaust the memory of every node that validates it. The group Bitcoin removed is now disabled and pushes are capped at 520 bytes.
  • CVE-2012-2459. BuildMerkleTree duplicates the trailing hash on odd-width levels, so appending a copy of the last transaction yields a block with an identical merkle root — and identical block hash — to a legitimate one. Nodes rejected the forgery, cached that hash as bad, then refused the genuine block. Blocks carrying a duplicate transaction are now rejected.
  • Halving height. The subsidy was halved on nBestHeight, the validating node's own tip, instead of the height of the block being valued. Across a halving, nodes at different sync heights would disagree about the same block and follow different chains.

This is a consensus change

A node still on v1.2.0 or earlier will accept a spend that upgraded nodes reject, and will follow the wrong chain. Upgrade every node you run, including headless miners.

Verified against the live chain before release: a node with the new rules synced all 2443 existing blocks from genesis with zero rejections — nothing in use relies on the removed opcodes, and no existing transaction changes validity.

Found in a review of the consensus and script code against the vulnerabilities Bitcoin fixed after 0.1.0. Fix in #12.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions