Skip to content

Commit 7f11ef2

Browse files
committed
Merge #9937: rpc: Prevent dumpwallet from overwriting files
0cd9273 rpc: Prevent `dumpwallet` from overwriting files (Wladimir J. van der Laan) Pull request description: Prevent arbitrary files from being overwritten by `dumpwallet`. There have been reports that users have overwritten wallet files this way. It may also avoid other security issues. Fixes #9934. Adds mention to release notes and adds a test. Tree-SHA512: 268c98636d40924d793b55a685a0b419bafd834ad369edaec08227ebe26ed4470ddea73008d1c4beb10ea445db1b0bb8e3546ba8fc2d1a411ebd4a0de8ce9120
2 parents a1f7f18 + 0cd9273 commit 7f11ef2

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

doc/release-notes.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ Low-level RPC changes
8383
* `getwalletinfo`
8484
* `getmininginfo`
8585

86+
- `dumpwallet` no longer allows overwriting files. This is a security measure
87+
as well as prevents dangerous user mistakes.
88+
8689
Credits
8790
=======
8891

src/wallet/rpcdump.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
600600
if (request.fHelp || request.params.size() != 1)
601601
throw std::runtime_error(
602602
"dumpwallet \"filename\"\n"
603-
"\nDumps all wallet keys in a human-readable format.\n"
603+
"\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n"
604604
"\nArguments:\n"
605605
"1. \"filename\" (string, required) The filename with path (either absolute or relative to bitcoind)\n"
606606
"\nResult:\n"
@@ -616,9 +616,19 @@ UniValue dumpwallet(const JSONRPCRequest& request)
616616

617617
EnsureWalletIsUnlocked(pwallet);
618618

619-
std::ofstream file;
620619
boost::filesystem::path filepath = request.params[0].get_str();
621620
filepath = boost::filesystem::absolute(filepath);
621+
622+
/* Prevent arbitrary files from being overwritten. There have been reports
623+
* that users have overwritten wallet files this way:
624+
* https://github.com/bitcoin/bitcoin/issues/9934
625+
* It may also avoid other security issues.
626+
*/
627+
if (boost::filesystem::exists(filepath)) {
628+
throw JSONRPCError(RPC_INVALID_PARAMETER, filepath.string() + " already exists. If you are sure this is what you want, move it out of the way first");
629+
}
630+
631+
std::ofstream file;
622632
file.open(filepath.string().c_str());
623633
if (!file.is_open())
624634
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");

test/functional/wallet-dump.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88

99
from test_framework.test_framework import BitcoinTestFramework
10-
from test_framework.util import assert_equal
10+
from test_framework.util import (assert_equal, assert_raises_jsonrpc)
1111

1212

1313
def read_dump(file_name, addrs, hd_master_addr_old):
@@ -105,5 +105,8 @@ def run_test (self):
105105
assert_equal(found_addr_chg, 90*2 + 50) # old reserve keys are marked as change now
106106
assert_equal(found_addr_rsv, 90*2)
107107

108+
# Overwriting should fail
109+
assert_raises_jsonrpc(-8, "already exists", self.nodes[0].dumpwallet, tmpdir + "/node0/wallet.unencrypted.dump")
110+
108111
if __name__ == '__main__':
109112
WalletDumpTest().main ()

0 commit comments

Comments
 (0)