mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
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:
committed by
seelabs
parent
125316f2a6
commit
6328fabd5c
@@ -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,
|
||||
|
||||
@@ -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\"");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user