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

Hold the parent key in each cache entry

Public commit record

What the developer wrote

Authored by kdmukai

80/100 · Strong
Hold the parent key in each cache entry

The cache keys on id(parent_key), which is the parent's address in
memory. Python is free to hand that address to a new object once the
original is released, so an entry outliving its parent could be matched
by an unrelated key that landed on the same address, and
_derive_with_cache would return that entry's child instead of deriving
the right one. It fails silently: a recycled address is
indistinguishable from a hit.

Nothing triggers this today, because every parent -- the signing seed's
root and the cosigner xpubs from psbt.xpubs -- is held for the whole
parse. But that is a property of the call sites rather than of the
function, and the failure would be a wrong key in the middle of change
detection.

Storing the parent alongside its derived child keeps that address
occupied for as long as the entry depending on it is alive. The entry
holds a reference to a key the parser already owns, so nothing new is
retained and nothing is copied. Costs 56 bytes per entry, so the cap now
holds the cache to about 600 KB; the comment is updated to match.

Reported by newtonick in review.
✓ Descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Explains rationale or failure mode
The short version

What changed, and why it matters

This commit fixes a subtle caching bug in how SeedSigner derives child keys from parent keys when parsing Bitcoin transactions. The cache used the memory address of the parent key as its identifier, but Python can reuse that address after the parent is discarded. In theory, an unrelated new parent could land on the same address, causing the cache to return the wrong child key without any error. The fix stores the parent key inside each cache entry so its memory address stays occupied as long as the cached result exists. The commit itself says nothing currently triggers the bug because callers keep parents alive, but the function was unsafe on its own.

Recommended action

Treat this as a defensive correctness fix with latent security implications. Review whether any other components use id() as a cache key for cryptographic material. No immediate emergency response is indicated because the commit states current call sites keep parents alive, but the patch should be included in the next release.

Security signals we found

01

Use of id() as a cache key for security-critical objects

02

Potential use-after-free / object identity reuse in Python cache

03

Silent wrong-key return in key derivation path

04

Change-detection key derivation correctness

05

Memory cap adjustment to account for parent reference storage

Risk score

Why this scored 59/100

Our methodology →
Potential impact 18/30
Exploitability 8/25
Stealth signal 12/15
Affected reach 10/15
Confidence 7/10
Evidence quality 4/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.