Improve log scrubbing:

Per issue #2354, when the log level of a server was configured at
"trace", sensitive keying meterial generated by the `wallet_propose`
command could be written to the server's log file, if one was
configured.

This commit improves the log scrubbing code to account for the
sensitive information generated by a `wallet_propose`.

** Important security consideration **

We still caution everyone *against* executing this command on a
server that they do not control: a malicious server operator could
intercept the generated keypair, or operate a modified server that
returns keypairs that are not securely generated.
This commit is contained in:
Nikolaos D. Bougalis
2018-01-25 16:34:21 -08:00
committed by seelabs
parent 125316f2a6
commit 6328fabd5c
2 changed files with 34 additions and 25 deletions

View File

@@ -230,10 +230,6 @@ private:
maximumMessageCharacters = 12 * 1024
};
static
std::string
scrub (std::string s);
static
void
format (std::string& output, std::string const& message,

View File

@@ -289,26 +289,6 @@ Logs::fromString (std::string const& s)
return lsINVALID;
}
// Replace the first secret, if any, with asterisks
std::string
Logs::scrub (std::string s)
{
using namespace std;
char const* secretToken = "\"secret\"";
// Look for the first occurrence of "secret" in the string.
size_t startingPosition = s.find (secretToken);
if (startingPosition != string::npos)
{
// Found it, advance past the token.
startingPosition += strlen (secretToken);
// Replace the next 35 characters at most, without overwriting the end.
size_t endingPosition = std::min (startingPosition + 35, s.size () - 1);
for (size_t i = startingPosition; i < endingPosition; ++i)
s [i] = '*';
}
return s;
}
void
Logs::format (std::string& output, std::string const& message,
beast::severities::Severity severity, std::string const& partition)
@@ -334,13 +314,46 @@ Logs::format (std::string& output, std::string const& message,
case kFatal: output += "FTL "; break;
}
output += scrub (message);
output += message;
// Limit the maximum length of the output
if (output.size() > maximumMessageCharacters)
{
output.resize (maximumMessageCharacters - 3);
output += "...";
}
// Attempt to prevent sensitive information from appearing in log files by
// redacting it with asterisks.
auto scrubber = [&output](char const* token)
{
auto first = output.find(token);
// If we have found the specified token, then attempt to isolate the
// sensitive data (it's enclosed by double quotes) and mask it off:
if (first != std::string::npos)
{
first = output.find ('\"', first + std::strlen(token));
if (first != std::string::npos)
{
auto last = output.find('\"', ++first);
if (last == std::string::npos)
last = output.size();
output.replace (first, last - first, last - first, '*');
}
}
};
scrubber ("\"seed\"");
scrubber ("\"seed_hex\"");
scrubber ("\"secret\"");
scrubber ("\"master_key\"");
scrubber ("\"master_seed\"");
scrubber ("\"master_seed_hex\"");
scrubber ("\"passphrase\"");
}
//------------------------------------------------------------------------------