AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
High 79 Bitcoin

Verify that change outputs actually pay this seed

Public commit record

What the developer wrote

Authored by kdmukai

78/100 · Adequate
Verify that change outputs actually pay this seed

An output counted as change when its policy matched the inputs' and its
rebuilt scriptPubKey matched what the output committed to. Neither step
established that the key involved was ours. The policy comparison
included cosigners resolved from the coordinator's own global xpubs, so
one misannotated fingerprint made an output stop matching and skip
verification altogether, and multisig never checked our key against the
committed script at all.

Outputs now compare on script shape alone, and every candidate proves
ownership: single sig by rebuilding from the claimed derivation path,
multisig by finding this seed's key in the committed script. Where the
psbt's account of an output contradicts what the output commits to, the
parse refuses rather than quietly reclassifying. A claim set too
malformed to answer that question, one populating both derivation path
maps or claiming more keys than its script uses, is refused as well.

change_data now carries the verified derivation path in place of the
coordinator's claimed fingerprints and paths, so the views no longer
re-derive trust from strings the parse has already settled.

Taproot mismatches stay exempt. A script tree tweaks the internal key,
so honest taproot change fails the rebuild too, and embit leaves
PSBT_OUT_TAP_TREE unparsed, which is what would tell the two apart.
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification
The short version

What changed, and why it matters

This commit fixes a security flaw in how SeedSigner decides whether a Bitcoin transaction's 'change' output really returns coins to the user's own wallet. Previously, the device trusted too much of what the transaction coordinator (or a malicious wallet app) claimed about output ownership, which could let an attacker trick the user into approving a payment that actually sends change to the attacker. The fix makes the device independently prove ownership of each change output using the seed's own keys, and it now rejects several kinds of contradictory or misleading PSBT annotations as attacks.

Recommended action

Treat this commit as a security fix and include it in the next release. Review the taproot exemption note (PSBT_OUT_TAP_TREE parsing) for follow-up hardening, since honest taproot change with a script tree is currently misclassified as an external spend rather than verified as change.

Security signals we found

01

Fixes insufficient verification of change output ownership in PSBT parsing

02

Adds explicit rejection of ownership-claim/scriptPubKey contradictions treated as attacks

03

Adds rejection of surplus derivation path entries and mixed ecdsa/taproot derivation maps

04

Removes reliance on coordinator-supplied fingerprints/paths for change classification

05

Adds new exception classes: PSBTSurplusDerivationPathsError, PSBTMixedDerivationPathTypesError, PSBTOutputOwnershipContradictionError

06

Updates UI to warn user and discard suspicious PSBTs

07

Includes extensive regression tests for single-sig, multisig, and taproot deception scenarios

Risk score

Why this scored 79/100

Our methodology →
Potential impact 25/30
Exploitability 18/25
Stealth signal 12/15
Affected reach 10/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.