Ash
Ash

Reputation: 203

Fortify Json Injection in .NET

I am using Newtonsoft.Json for deserializing a json string but fortify complained that I am using unvalidated json. i then added a check using Newtonsoft.Json.Schema but it now complains even more

var schema = JsonSchema.Parse(JsonConvert.SerializeObject(typeof(T)));
JToken token = JArray.Parse(json); -- Vulnerability
IList<string> errors;
if (token.IsValid(schema, out errors))
{
    return JsonConvert.DeserializeObject<T>(json); -- Vulnerability
}

Any advice on how to validate Json string?

On line 23 of , the method DeserializeObject() writes unvalidated input into JSON. This call could allow an attacker to inject arbitrary elements or attributes into the JSON entity.

Upvotes: 7

Views: 14613

Answers (3)

Arun662469
Arun662469

Reputation: 97

If someone is still looking for a solution, i have done the following and it seems to be working as expected.

1 Get the JSON sample and infer schema using online tools.

2 Add a separate method to Validate JSON before parsing or deserializing it.

3 After validating the JSON using Schema then proceed for the normal operation whatever you wanted to do.

Upvotes: 1

oldbam
oldbam

Reputation: 2487

It looks like in your case Fortify complains that you use json from untrusted source, this is what is said in Fortify documentation:

The semantics of JSON documents and messages can be altered if an application constructs JSON from unvalidated input. In a relatively benign case, an attacker may be able to insert extraneous elements that cause an application to throw an exception while parsing a JSON document or request. In a more serious case, such as that involving JSON injection, an attacker may be able to insert extraneous elements that allow for the predictable manipulation of business critical values within a JSON document or request.

If you receive json from a web service that you own, you can probably disregard Fortify's warning. However, keep in mind that you are calling JArray.Parse() on the input and presume it will be a valid array, but if it isn't, you would get JsonReaderException. Also, you don't really validate your JSON against a schema, please, see JSON.NET example to see how to specify JSON schema.

To be honest, I would be interested to know myself how Fortify would expect one to validate JSON received from some third-party web service.

Upvotes: 4

Ash
Ash

Reputation: 203

Apologies for the late response, I managed to fix/deceive fortify. Here is the fix

byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
using (var stream = new MemoryStream(jsonBytes))
{
    output = Deserialize<List<T>>(stream);
}

 public TResult Deserialize<TResult>(Stream responseStream)
    {
        using (var sr = new StreamReader(responseStream))
        {
            using (var reader = new JsonTextReader(sr))
            {
                var serializer = new JsonSerializer
                {
                    MissingMemberHandling =
                        EnforceMissingMemberHandling ? MissingMemberHandling.Error : MissingMemberHandling.Ignore,
                    NullValueHandling = IgnoreNullValues ? NullValueHandling.Ignore : NullValueHandling.Include
                };

                return serializer.Deserialize<TResult>(reader);
            }
        }
    }

Hope this helps someone

Upvotes: 11

Related Questions