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.
dumpwallet
from overwriting files
#9937
The change as written now allows to test the existence of any file.
That seems preferable to overwriting any file, right? I tend to agree that being able to write arbitrary non-existing files is still a security risk, but it is tons better than what we have now.
Do you have a suggestion that would avoid this usage but still offers the same functionality?
only downside I see to this is an in automated backup that leaves files behind, your backup will stop and you might not notice. (I think that is a preferable failure mode to what we have now)
Suggestion: simply append a counter, or a date, or uniq-id. This is safer, too.
Note that it throws an exception when the attempt fails, so if you don’t notice you’re not handling errors at all, which is dangerous for a ton of other reasons too.
Do you have a suggestion that would avoid this usage but still offers the same functionality?
We could make the check even stricter, only allowing writing of files within the data directory, or even better a dumpwallet
directory within the data directory. It could even come up with its own unique filename and return that (e.g. #9740). But that has a much larger impact to the API. Could do that for 0.15 but certainly not for backporting.
623+ /* Prevent arbitrary files from being overwritten. There have been reports
624+ * that users have overwritten wallet files this way:
625+ * https://github.com/bitcoin/bitcoin/issues/9934
626+ * It may also avoid other security issues.
627+ */
628+ if (boost::filesystem::exists(filepath)) {
What if a dumpwallet
is executed after this check with the same filename, or the filename is created by other means? IMO we should use fopen
with wx
mode where x
stands for:
File access mode flag “x” can optionally be appended to “w” or “w+” specifiers. This flag forces the function to fail if the file exists, instead of overwriting it. (C11)
and drop exists()
test.
/some/base/path/ + wallet-name + some-timestamp + .extension
and return the filename.
599@@ -600,7 +600,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
600 if (request.fHelp || request.params.size() != 1)
601 throw std::runtime_error(
602 "dumpwallet \"filename\"\n"
603- "\nDumps all wallet keys in a human-readable format.\n"
604+ "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n"
605 "\nArguments:\n"
606 "1. \"filename\" (string, required) The filename with path (either absolute or relative to bitcoind)\n"
This help text is misleading. The relative path is relative to the directory from where bitcoind was started.
(really I think we should disallow relative paths entirely unless they’re relative to some fixed point like the datadir)
615@@ -616,9 +616,19 @@ UniValue dumpwallet(const JSONRPCRequest& request)
616
617 EnsureWalletIsUnlocked(pwallet);
618
619- std::ofstream file;
620 boost::filesystem::path filepath = request.params[0].get_str();
621 filepath = boost::filesystem::absolute(filepath);
622+
623+ /* Prevent arbitrary files from being overwritten. There have been reports
624+ * that users have overwritten wallet files this way:
625+ * https://github.com/bitcoin/bitcoin/issues/9934
626+ * It may also avoid other security issues.
627+ */
628+ if (boost::filesystem::exists(filepath)) {
629+ throw JSONRPCError(RPC_INVALID_PARAMETER, filename.string() + " already exists. If you are sure this is what you want, move it out of the way first");
filename
should be filepath
?
Concept ACK, but currently fails to build :(
A few comments inline.
And there is also the option to make the filename optional, where the default value is /some/base/path/ + wallet-name + some-timestamp + .extension and return the filename.
Yes, many other things are possible. I’m not going to do that here. That’s the reason I closed this before. However I only want to solve the overwrite problem here, which is not solved by making up filenames, only by refusing to overwrite files.
Prevent arbitrary files from being overwritten. 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.
Requires release notes (although this is fixing up undefined behaviour, there may be users who currently rely on that behaviour)
A release notes change is already part of the PR.
laanwj
sipa
jonasschnelli
MarcoFalke
paveljanik
gmaxwell
promag
sdaftuar
jnewbery
Labels
RPC/REST/ZMQ
Milestone
0.15.2