Skip to content

DecodeTxErr: prevent potential DoS caused by a malformed tx or block - #5

Open
ronny wants to merge 1 commit into
dogeorg:mainfrom
ronny:fix-decode-tx-malformed-input
Open

DecodeTxErr: prevent potential DoS caused by a malformed tx or block#5
ronny wants to merge 1 commit into
dogeorg:mainfrom
ronny:fix-decode-tx-malformed-input

Conversation

@ronny

@ronny ronny commented May 19, 2026

Copy link
Copy Markdown
Contributor

A malformed tx or block with a varint count claiming more entries than the remaining buffer could possibly encode (e.g. a 0xff prefix declaring max-uint64 inputs) would make readVinVout/readBlock/readMerkleBranch loop billions of times against an exhausted stream, growing slices of zero-valued records until OOM. recover() in consumers can't catch this — the goroutine never panics, it just never returns.

This change adds tight lower-bound size constants (minTxInBytes=41, minTxOutBytes=9, minTxBytes=60, minHashBytes=32) and rejects any varint count that would exceed remaining-bytes / min-per-element. Applied at every varint-driven loop in block.go: tx_count, merkle-branch hashes, vin_count, vout_count, and the witness stack count + per-item length.

TestDecodeTxErr_MaliciousVinCount covers both the huge-varint case and the truncated-count case under a 500ms deadline, so a regression fails the test instead of hanging CI.

Comment thread block.go Outdated
A malformed tx or block with a varint count claiming more entries than the
remaining buffer could possibly encode (e.g. a 0xff prefix declaring
max-uint64 inputs) would make readVinVout/readBlock/readMerkleBranch loop
billions of times against an exhausted stream, growing slices of
zero-valued records until OOM. Recover() in consumers can't catch this —
the goroutine never panics, it just never returns.

Add tight lower-bound size constants (minTxInBytes=41, minTxOutBytes=9,
minTxBytes=60, minHashBytes=32) and reject any varint count that would
exceed remaining-bytes / min-per-element. Applied at every varint-driven
loop in block.go: tx_count, merkle-branch hashes, vin_count, vout_count,
and the witness stack count + per-item length.

TestDecodeTxErr_MaliciousVinCount covers both the huge-varint case and
the truncated-count case under a 500ms deadline, so a regression fails
the test instead of hanging CI.
@ronny
ronny force-pushed the fix-decode-tx-malformed-input branch from 52b3f39 to ee83c3f Compare May 20, 2026 02:38

@raffecat raffecat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

@ronny

ronny commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@raffecat @SomeoneWeird could either of you please merge if this is good to go? I don't have access.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants