RUSTSEC-2026-0500: BEEF validation answers valid for a raw entry that is not a transaction
Beef::mergerawtx and BeefTx::fromrawtx accept raw bytes without a Result. For bytes that are not exactly one transaction (a transaction followed by bytes, a cut transaction, bytes that are no transaction at all), Beef::sorttxs, verifystructure, verifyvalid and isvalid could answer valid, even with no BUMP and no parent in the BEEF, and, where the entry carried a BUMP index, treat the hash of those bytes as a proven transaction id; an entry that names it as a parent was answered valid too.
The wire readers (Beef::frombinary, verifystream, Transaction::frombeef, fromatomicbeef) parse every entry and are not affected. Reaching this needs an application that passes bytes it did not parse to mergerawtx or BeefTx::fromrawtx and then relies on the verdict or on the transaction the BEEF hands back.
0.8.5 refuses such an entry at all four verdict doors, with or without a BUMP index, and every entry that names it as a parent. Where upgrading is not possible, do not rely on isvalid or verifyvalid alone for such an entry: check that the bytes are exactly one transaction before merging them.
Other sources
Transaction::frombinary and Transaction::fromhex read one transaction from the front of their input, did not check that the input ended there, and kept the whole input as the transaction's cached serialization: tobinary, tohex and id() then answered for bytes that are not the transaction's. Transaction::fromjson, given a hex field, reads it through fromhex and answers the same. fromef, fromhexef and parsescriptoffsets also read a prefix.
An application that takes bytes or hex from outside, parses them with these readers and then uses id() or the serialization could be given one transaction under another identity: the same parsed fields, a different id. An application that passes them only bytes it produced or has already checked is not affected.
0.8.5 refuses a byte after the transaction; Transaction::fromreader reads from the front of a longer buffer. Where upgrading is not possible, parse with Transaction::frombinary, call tx.invalidatecaches() (public from 0.3.16) and require tx.tobinary() == bytes.
— OSV
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
rust/bsv-rsto a version that resolves this vulnerability.Fixed in 0.8.5 - Upgrade
Upgrade
rust/bsv-rsto a version that resolves this vulnerability.Fixed in 0.9.0-beta.7.0 - Upgrade
Upgrade
BEEF libraryto a version that resolves this vulnerability.Fixed in 0.8.5 - Compensating control
Where upgrading is not possible, parse externally supplied transaction bytes and require that the serialization of the parsed transaction exactly equals the complete input (tx.to_binary() == bytes) before merging or accepting it; do not rely on is_valid or verify_valid alone for such entries.
- Operational
After calling Transaction::from_binary, call tx.invalidate_caches() before using cached serialization or transaction identity methods such as to_binary or id().
Event History
Frequently Asked Questions
Which applications are exposed to this issue?
Applications are exposed only if they pass unparsed, externally supplied bytes to Beef::merge_raw_tx or BeefTx::from_raw_tx and then rely on a BEEF validity verdict or on the transaction returned by the BEEF. The binary wire readers parse every entry and are not affected.
What malformed input can be treated as valid?
Inputs that are not exactly one transaction can be accepted, including a transaction followed by additional bytes, a truncated transaction, or bytes that are not a transaction. These entries may be reported valid even without a BUMP or parent, and may also be treated as a proven transaction ID when they carry a BUMP index.
How can this be mitigated before upgrading?
Do not rely on is_valid or verify_valid alone for entries created from raw bytes. Before merging, verify that the bytes represent exactly one transaction; Transaction::from_binary and Transaction::from_hex are identified as parsing options.
What version changes the affected validation behavior?
Version 0.8.5 refuses malformed raw entries at sort_txs, verify_structure, verify_valid, and is_valid, regardless of whether they have a BUMP index. It also rejects entries that name such malformed entries as parents.