Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET SerializeObject escape values to prevent XSS

Using Json.NET

JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" })

returns

{"Property":"<script>alert('o hai');</script>"}

Is it possible for the value to be escaped by SerializeObject to prevent a hostile script from executing? I'd prefer not to make changes to the object itself.

Edit: Ideally I'd like to integrate the sanitizing into the SerializeObject call without having to process the object before or after SerializeObject.

Edit: The string output from JsonConvert.SerializeObject is assigned to a global variable in a script block, which I believe is where the XSS issue is.

like image 321
kendaleiv Avatar asked May 25 '12 14:05

kendaleiv


2 Answers

Functionality to achieve this was added in version 4.5.11

This allows you to add various type of escaping to the output.

This is my LinqPad test:

    var settings = new JsonSerializerSettings();

    settings.StringEscapeHandling = StringEscapeHandling.EscapeHtml;

    var output = JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" }, settings);

    Debug.Print(output);

outputs

{"Property":"\u003cscript\u003ealert(\u0027o hai\u0027);\u003c/script\u003e"}

Just as a disclaimer, this isn't a golden bullet to fix xss, but should help you mitigate it a bit given your example.

like image 126
John Perrin Avatar answered Oct 14 '22 17:10

John Perrin


This may not be ideal but this is my solution (for now, at least):

JsonConvert.SerializeObject(new { Property = "<script>alert('o hai');</script>" }, new HtmlEncodeStringPropertiesConverter());

with a simple JsonConverter that performs HtmlEncode on the value if it is a string

public class HtmlEncodeStringPropertiesConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(Encoder.HtmlEncode(value.ToString()));
    }
}

(Encoder is Microsoft.Security.Application.Encoder from the AntiXSS library)

like image 41
kendaleiv Avatar answered Oct 14 '22 17:10

kendaleiv