提问者:小点点

Json.NET序列化对象转义值以防止XSS


使用Json.NET

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

回报

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

是否可以通过SeriezeObject转义该值以防止恶意脚本执行?我不希望对对象本身进行更改。

编辑:理想情况下,我想将清理集成到序列化对象调用中,而无需在序列化对象之前或之后处理对象。

编辑:从JsonConver. SeriezeObject输出的字符串被分配给脚本块中的全局变量,我相信这就是XSS问题所在。


共3个答案

匿名用户

4.5.11版增加了实现这一点的功能

这允许您向输出添加各种类型的转义。

这是我的 LinqPad 测试:

    var settings = new JsonSerializerSettings();

    settings.StringEscapeHandling = StringEscapeHandling.EscapeHtml;

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

    Debug.Print(output);

输出

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

作为一个免责声明,这不是修复xss的黄金子弹,但应该有助于减轻您的示例中的问题。

匿名用户

这可能不理想,但这是我的解决方案(至少目前是这样):

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

使用一个简单的JsonConverter,如果值是字符串,则对其执行HtmlEncode

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是来自AntiXSS库的Microsoft. Security. Application. Encoder

匿名用户

在 .NET Core 3.0 中,System.Text.Json.JsonSerializer 默认转义 html 字符。

var text = "<script>alert('o hai');</script>";

var json = System.Text.Json.JsonSerializer.Serialize(new { Property = text });

Console.WriteLine(json);

输出

// .NETCoreApp,Version=v3.0
{"Property":"\u003Cscript\u003Ealert(\u0027o hai\u0027);\u003C/script\u003E"}

如何序列化和反序列化JSON。NET中的序列化行为部分说:

默认编码器对非ASCII字符、ASCII范围内的HTML敏感字符以及根据JSON规范必须转义的字符进行转义。

也请检查JavaScriptEncoder的备注。UnsafeRelaxedJsonEscaping,因为它包含一系列以不像缺省值开头的注释。

<代码> JavaScriptEncoder。需要设置UnsafeRelaxedJsonEscaping 来关闭默认行为。

var options = new System.Text.Json.JsonSerializerOptions() { 
  Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
var json2 = System.Text.Json.JsonSerializer.Serialize(new { Property = text }, options); 
Console.WriteLine(json2);
{"Property":"<script>alert('o hai');</script>"}

备注 不安全放松Json逃生

与默认编码器不同,此编码器实例不会转义 HTML 敏感字符,例如

与默认编码不同,引号被编码为“而不是”。

与默认编码(仅允许UnicodeRanges.BasicLatin)不同,使用此编码器实例允许UnicodeRange。所有这些都将在无遮挡的情况下进行。

与默认编码器不同,此编码器实例允许某些其他字符(如“”)不经过转义,因此必须谨慎使用。