Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mask sensitive values in JSON for logging purposes

Tags:

json

json.net

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.

like image 813
Nick Jacobs Avatar asked Jun 14 '16 20:06

Nick Jacobs


People also ask

How do I mask sensitive data in logs?

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.

How do I mask sensitive data in Java logs using log4j?

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.

What is mask in JSON?

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.


1 Answers

Here is the approach I think I would take:

  1. 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);
    }
    
  2. 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())));
            }
        }
    }
    
  3. 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.

  4. 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

like image 154
Brian Rogers Avatar answered Oct 10 '22 23:10

Brian Rogers