I have several similar JSON structures that I want to write into a SQL table for logging purposes. However, some of the fields in the JSON contain sensitive information, which I want to partially mask so the full value is not visible in the log.
Here is an example of one of the JSON structures:
{
"Vault": 1,
"Transaction": {
"gateway": {
"Login": "Nick",
"Password": "Password"
},
"credit_card": {
"number": "4111111111111"
}
}
}
In this case I'm trying to change the 4111
credit card number so that it appears like 4xxx1111
in the JSON. I am using Newtonsoft and have deserialized the JSON into a JObject
, but I am stuck on how to mask the value. I think the clue is something with JToken
, but haven't figured it out yet. I'd like to make the solution as generic as possible so that it will work with any JSON structure that I might need to log out.
Any help would be appreciated.
To mask personal data in Log Monitoring, a masking rule and a masking rule scope need to be added to the configuration file for each OneAgent. The masking rule defines what data is masked, while the masking rule scope defines to what log files the rule is applied. The masking is done in the OneAgent.
You can prevent sensitive data from being logged in the verbose log messages by filtering log messages when using the log4j utility for logging. This helps prevent sensitive information, such as CVV2 codes, from being logged in the verbose log messages.
The JSON mask is designed to mask property values within a JSON record. A JSON mask can contain one or more path expressions. All of the path expressions and related masks within a JSON mask shall be applied to each JSON record processed.
Here is the approach I think I would take:
Make a helper method that can take a string value and obscure it in the manner you require for your log. Maybe something like this, for example:
public static string Obscure(string s)
{
if (string.IsNullOrEmpty(s)) return s;
int len = s.Length;
int leftLen = len > 4 ? 1 : 0;
int rightLen = len > 6 ? Math.Min((len - 6) / 2, 4) : 0;
return s.Substring(0, leftLen) +
new string('*', len - leftLen - rightLen) +
s.Substring(len - rightLen);
}
Make another helper method that can accept a JToken
and a list of JSONPath expressions. In this method, match each path against the contents of the token using SelectTokens
. For each match found, use the first helper method to replace the sensitive value with an obscured version.
public static void ObscureMatchingValues(JToken token, IEnumerable<string> jsonPaths)
{
foreach (string path in jsonPaths)
{
foreach (JToken match in token.SelectTokens(path))
{
match.Replace(new JValue(Obscure(match.ToString())));
}
}
}
Finally, compile a list of JSONPath expressions for the values that you want to obscure across all the JSON bodies you expect to get. From your example JSON above, I think you would want to obscure Password
wherever it occurs and number
if it occurs inside credit_card
. Expressed as JSONPath, these would be $..Password
and $..credit_card.number
, respectively. (Keep in mind that JSONPath expressions are case sensitive in Json.Net.) Take this list and put it into a configuration setting somewhere so you can change it easily when you need to.
Now, whenever you want to log out some JSON, just do this:
JToken token = JToken.Parse(json);
string[] jsonPaths = YourConfigSettings.GetJsonPathsToObscure();
ObscureMatchingValues(token, jsonPaths);
YourLogger.Log(token.ToString(Formatting.None));
Demo fiddle: https://dotnetfiddle.net/dGPyJF
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With