How to mask sensitive values in JSON for logging purposes

时光毁灭记忆、已成空白 提交于 2021-02-05 05:01:41

问题


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.


回答1:


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



来源:https://stackoverflow.com/questions/37821298/how-to-mask-sensitive-values-in-json-for-logging-purposes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!