Merge bitcoin/bitcoin#26186: rpc: Sanitize label name in various RPCs with tests

65e78bda7c test: Invalid label name coverage (Aurèle Oulès)
552b51e682 refactor: Add sanity checks in LabelFromValue (Aurèle Oulès)
67e7ba8e1a rpc: Sanitize label name in various RPCs (Aurèle Oulès)

Pull request description:

  The following RPCs did not sanitize the optional label name:
  - importprivkey
  - importaddress
  - importpubkey
  - importmulti
  - importdescriptors
  - listsinceblock

  Thus is was possible to import an address with a label `*` which should not be possible.
  The wildcard label is used for backwards compatibility in the `listtransactions` rpc.
  I added test coverage for these RPCs.

ACKs for top commit:
  ajtowns:
    ACK 65e78bda7c
  achow101:
    ACK 65e78bda7c
  furszy:
    diff ACK 65e78bd
  stickies-v:
    re-ACK 65e78bda7c
  theStack:
    re-ACK 65e78bda7c

Tree-SHA512: ad99f2824d4cfae352166b76da4ca0069b7c2eccf81aaa0654be25bbb3c6e5d6b005d93960f3f4154155f80e12be2d0cebd5529922ae3d2a36ee4eed82440b31
This commit is contained in:
Andrew Chow
2023-01-10 17:22:21 -05:00
5 changed files with 56 additions and 24 deletions

View File

@ -28,6 +28,44 @@ class WalletLabelsTest(BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_wallet()
def invalid_label_name_test(self):
node = self.nodes[0]
address = node.getnewaddress()
pubkey = node.getaddressinfo(address)['pubkey']
rpc_calls = [
[node.getnewaddress],
[node.setlabel, address],
[node.getaddressesbylabel],
[node.importpubkey, pubkey],
[node.addmultisigaddress, 1, [pubkey]],
[node.getreceivedbylabel],
[node.listsinceblock, node.getblockhash(0), 1, False, True, False],
]
if self.options.descriptors:
response = node.importdescriptors([{
'desc': f'pkh({pubkey})',
'label': '*',
'timestamp': 'now',
}])
else:
rpc_calls.extend([
[node.importprivkey, node.dumpprivkey(address)],
[node.importaddress, address],
])
response = node.importmulti([{
'scriptPubKey': {'address': address},
'label': '*',
'timestamp': 'now',
}])
assert_equal(response[0]['success'], False)
assert_equal(response[0]['error']['code'], -11)
assert_equal(response[0]['error']['message'], "Invalid label name")
for rpc_call in rpc_calls:
assert_raises_rpc_error(-11, "Invalid label name", *rpc_call, "*")
def run_test(self):
# Check that there's no UTXO on the node
node = self.nodes[0]
@ -138,6 +176,8 @@ class WalletLabelsTest(BitcoinTestFramework):
# in the label. This is a no-op.
change_label(node, labels[2].addresses[0], labels[2], labels[2])
self.invalid_label_name_test()
if self.options.descriptors:
# This is a descriptor wallet test because of segwit v1+ addresses
self.log.info('Check watchonly labels')