OSC-2026-0031 · github.com/trezor/trezor-firmware
info clean-run claude-fable-5 2026-08-04 signed: nostr
- Repository
- github.com/trezor/trezor-firmware
- Commit
- 2b1938cc4d0d1c00d0c484a8b794e7758fe89f5b
- Scope path
- core/src/apps/bitcoin/sign_tx/
- Model
- claude-fable-5
- Harness
- claude-code
- Prompts
- prompts/tx-authorization-audit-v1.md
- Independent runs
- 1
- Transcript sha256
- 8034f59a73c906bb194e44fafe0ec0678dedf5ca81280903e3ad086c9f174956
- Auditor
- TheIcarusWings (theicaruswings)
- Signature
- nostr-schnorr · npub19tzp8lf3klmqj3dz9mz0qnuvjp7uyy9993gmljmyaxs8phztj7wsnujvq5
Scope. Transaction-authorization class at HEAD 2b1938cc - second lens on the target audited for entropy in OSC-2026-0025. EXAMINED: the change-output decision (sign_tx/change_detector.py) and change-address derivation (sign_tx/bitcoin.py output_derive_script). EXPLICITLY NOT EXAMINED: input amount provenance and fee sanity (Trezor is the origin of the 2018 SegWit fee-attack advisory and its current input verification deserves its own record), the PrevTx streaming/hashing path, SignMessage, Decred and other altcoin implementations, the authorization.py CoinJoin path, and firmware update integrity.
Findings
info OSC-2026-0031-F1 unreviewed
No defect found in scope; the strongest change-output construction of the five signers audited under this pack, because it removes the attack surface rather than defending it. In output_derive_script (sign_tx/bitcoin.py ~961-982) the device OVERWRITES txo.address with an address derived from its own keychain (self.keychain.derive(txo.address_n)) for any output carrying address_n. Where Keystone3 and SeedSigner compare a host-supplied address against a derived one and reject on mismatch, Trezor never consults the host's address for a change output at all - the host can only supply a PATH, so there is nothing to spoof. output_is_change (sign_tx/change_detector.py ~45-68) then gates change status behind seven conjoined conditions: multisig fingerprint, wallet path prefix and script type must all match the INPUTS, plus path depth, change-chain index <= 1, last element <= 1,000,000, and amount > 0 - so an attacker cannot nominate an arbitrary in-wallet path either. Notable beyond this pack's scope: multisig outputs using different derivation paths per xpub are refused outright, with an in-source comment explaining it prevents a compromised host randomising address indices and ransoming the user for the paths; the 1,000,000 bound exists so a lost path stays brute-forceable. That is threat modelling well past the change-spoofing class.