是否需要在Razor视图中编码JsonConvert.SerializeObject的输出?

Jer*_*ook 13 javascript security asp.net-mvc razor

我使用Newtonsoft库将C#对象转换为JSON.这是使用Newtonsoft.Json.JsonConvert.SerializeObject安全,还是需要额外的编码?如果需要额外的编码,你有什么建议?

以下是我在Razor视图中使用它的方法:

<script type="text/javascript">
    var jsModel = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))
</script>
Run Code Online (Sandbox Code Playgroud)

Lev*_*evi 12

您至少需要对'\ u003C'执行'<'字符的额外编码,并将'>'字符执行到'\ u003E'.最后我检查了JSON.NET没有在字符串文字中编码这些字符.

我可能会因此而受到攻击,但我这样做的方法是在页面上呈现一个虚拟元素:

<div id="the-div" data-json="@JsonConvert.SerializeObject(Model)" />
Run Code Online (Sandbox Code Playgroud)

然后,在Javascript中,从-div元素中提取data-json属性值.这样做的好处是您不必担心哪些字符需要特殊编码.该方法保证 JSON blob格式正确,并且运算符保证在放入HTML属性之前,从JSON转换中遗留的任何剩余的非HTML安全字符都被正确转义(只要属性值被包围)用双引号,如上所述).所以,是的,它有点丑陋,但它可以有效地完全关闭整个类的漏洞.JSON.parseSerializeObject@


Jer*_*ook 6

@Html.Raw像问题一样单独使用肯定是危险的.这是在<script></script>标签内安全输出模型的另一种方法.我按照@Levi的例子来依赖浏览器的功能,以及微软的安全功能,并想出了这个:

var jsModel = JSON.parse("@Html.Raw(HttpUtility.JavaScriptStringEncode(
    JsonConvert.SerializeObject(Model)
))");
Run Code Online (Sandbox Code Playgroud)

我使用了以下非常简单的测试.如果我只@Html.Raw在问题中使用,则会显示"Bad"警告.以这种方式包装,我有有效的JavaScript,并且不会出现警报.

var jsModel = JSON.parse("@Html.Raw(HttpUtility.JavaScriptStringEncode(
    JsonConvert.SerializeObject(new {
        Test = "</script><script>var test = alert('Bad')</script>"
    })
))");
Run Code Online (Sandbox Code Playgroud)

下一步是将其包装在可重用的HtmlHelper扩展方法中.