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

Merge bitcoin/bitcoin#31514: wallet: allow label for non-ranged external descriptor (if `internal=false`) & disallow label for ranged descriptors

Public commit record

What the developer wrote

Authored by Ava Chow

91/100 · Strong
Merge bitcoin/bitcoin#31514: wallet: allow label for non-ranged external descriptor (if `internal=false`) & disallow label for ranged descriptors

664657ed134365588914c2cf6a3975ce368a4f49 bugfix: disallow label for ranged descriptors & allow external non-ranged descriptors to have label (scgbckbone)

Pull request description:

Motivation:
* ranged descriptors MUST not be able to have label (current impl allows it)
* external non-ranged descriptor MUST be able to have label (current impl disallows it, **if** `internal=false` is provided via importdescriptor user data)

Repro steps:
* create blank wallet and import descriptors
* external has `label=test` (not internal)
```
conn = bitcoind.create_wallet(wallet_name=w_name, disable_private_keys=True, blank=True,
passphrase=None, avoid_reuse=False, descriptors=True)
descriptors = [
{
"timestamp": "now",
"label": "test",
"active": True,
"desc": "wpkh([0f056943/84h/1h/0h]tpubDC7jGaaSE66Pn4dgtbAAstde4bCyhSUs4r3P8WhMVvPByvcRrzrwqSvpF9Ghx83Z1LfVugGRrSBko5UEKELCz9HoMv5qKmGq3fqnnbS5E9r/0/*)#erexmnep",
"internal": False
},
{
"desc": "wpkh([0f056943/84h/1h/0h]tpubDC7jGaaSE66Pn4dgtbAAstde4bCyhSUs4r3P8WhMVvPByvcRrzrwqSvpF9Ghx83Z1LfVugGRrSBko5UEKELCz9HoMv5qKmGq3fqnnbS5E9r/1/*)#ghu8xxfe",
"active": True,
"internal": True,
"timestamp": "now"
},
]
r = conn.importdescriptors(descriptors)
print(r)
```
response:
```
[{'error': {'code': -8,
'message': 'Internal addresses should not have a label'},
'success': False,
'warnings': ['Range not given, using default keypool range']},
{'success': True,
'warnings': ['Range not given, using default keypool range']}]
```
But in above, ONLY external has a label.

If you remove `internal: False` from external descriptor import object - it will import no problem:
```
[{'success': True,
'warnings': ['Range not given, using default keypool range']},
{'success': True,
'warnings': ['Range not given, using default keypool range']}]

```
Even tho it should NOT, as the descriptor is ranged. Current implementation relies on checking user provided data to decide whether desc is ranged.

ACKs for top commit:
achow101:
ACK 664657ed134365588914c2cf6a3975ce368a4f49
rkrux:
lgtm crACK 664657ed134365588914c2cf6a3975ce368a4f49

Tree-SHA512: 9e70aea620019c29950ba417d4ae38d65cd94a4f6fcabbc021d67b031de1c44c27d6f6f5cb7e6950a099eb6e58bed9be764d4c6347195daeccb14a5d95c123b2
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference
The short version

What changed, and why it matters

This commit fixes a wallet bug in Bitcoin Core's importdescriptors RPC. Previously, the code incorrectly decided whether a descriptor was 'internal' (change addresses) or 'ranged' (HD-style many addresses) based on user-supplied data rather than the descriptor itself. This meant users could accidentally attach a label to a ranged descriptor, which is not supposed to be allowed, and could be blocked from labeling a normal external descriptor when they explicitly set internal=false. The patch makes the check inspect the actual descriptor, so labels are allowed only on non-ranged external descriptors and disallowed on ranged ones. It is a correctness/validation bug, not a direct theft-of-funds vulnerability.

Recommended action

Treat as a low-severity wallet bug fix. Users relying on importdescriptors with labels should upgrade to a release containing this fix. No emergency action is required; no funds are at direct risk. Review the updated functional tests to confirm expected behavior.

Security signals we found

01

wallet descriptor import validation bug

02

label allowed on ranged descriptors (policy violation)

03

label disallowed on external non-ranged descriptors when internal=false explicitly set (false positive)

04

fix inspects descriptor IsRange() instead of relying solely on user input

05

no consensus, cryptography, or P2P networking changes

Risk score

Why this scored 25/100

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