我正在使用Newtonsoft JSON反序列化器。如何为XSS(跨站点脚本)清理JSON?在反序列化或编写某种自定义转换器/消毒剂之前清理JSON字符串?如果是这样 - 我不是百分之百确定最好的方法来解决这个问题。
下面是注入了危险脚本并需要“清理”的JSON示例。我希望在我对其进行反序列化之前管理它。但我们需要假设所有类型的XSS场景,包括BASE64编码脚本等,所以问题更复杂,简单的REGEX字符串替换。
{ "MyVar" : "hello<script>bad script code</script>world" }
以下是我的反序列化程序(JSON - &gt; Object)的快照:
public T Deserialize<T>(string json)
{
T obj;
var JSON = cleanJSON(json); //OPTION 1 sanitize here
var customConverter = new JSONSanitizer();// OPTION 2 create a custom converter
obj = JsonConvert.DeserializeObject<T>(json, customConverter);
return obj;
}
JSON是从第三方UI界面发布的,所以它公平,因此服务器端验证。从那里,它被序列化为各种对象,并且通常存储在DB中,以后可以直接在基于HTML的UI中检索和输出,因此必须减轻脚本注入。
答案 0 :(得分:3)
好的,我将尝试来保持这个相当短的时间,因为写下整个内容需要做很多工作。但是,基本上,您需要关注需要清理的数据的上下文。根据对原始帖子的评论,听起来JSON中的某些值将被用作将呈现的HTML,并且此HTML来自不受信任的来源。
第一步是提取需要作为HTML进行清理的JSON值,并且对于每个对象,您需要通过HTML解析器运行它们并剥离不在白名单中的所有内容。别忘了你还需要一个白名单属性。
HTML Agility Pack是在C#中解析HTML的一个很好的起点。在我看来,如何做这部分是一个单独的问题 - 可能是链接问题的重复。
我认为你对base64字符串的担心似乎有点过分强调了。它不像您可以简单地将aW5zZXJ0IGg0eCBoZXJl
放入HTML文档中,浏览器将呈现它。它可以通过javascript(你的白名单会阻止它)以及在某种程度上通过data:
网址滥用(但这不是坏事,因为javascript将在数据页面的上下文中运行。很好,但你不会自动吞噬饼干)。如果您必须允许a
标记,则部分过程需要验证URL是否为http(s)(或您想要允许的任何方案)。
理想情况下,你会避免这种不舒服的情况,而是使用类似markdown的东西 - 那么你可以简单地转义HTML字符串,但这并不总是我们可以控制的。您仍然需要进行一些URL验证。
答案 1 :(得分:2)
有趣!!谢谢你的询问。我们通常在Web表单方面使用html.urlencode。我有一个运行的企业web api,它有这样的验证。我们创建了一个自定义正则表达式来验证。请看一下这个 MSDN link。
这是为解析名为KeyValue(例如)
的请求而创建的示例模型public class KeyValue
{
public string Key { get; set; }
}
第1步:尝试使用自定义正则表达式
var json = @"[{ 'MyVar' : 'hello<script>bad script code</script>world' }]";
JArray readArray = JArray.Parse(json);
IList<KeyValue> blogPost = readArray.Select(p => new KeyValue { Key = (string)p["MyVar"] }).ToList();
if (!Regex.IsMatch(blogPost.ToString(),
@"^[\p{L}\p{Zs}\p{Lu}\p{Ll}\']{1,40}$"))
Console.WriteLine("InValid");
// ^ means start looking at this position.
// \p{ ..} matches any character in the named character class specified by {..}.
// {L} performs a left-to-right match.
// {Lu} performs a match of uppercase.
// {Ll} performs a match of lowercase.
// {Zs} matches separator and space.
// 'matches apostrophe.
// {1,40} specifies the number of characters: no less than 1 and no more than 40.
// $ means stop looking at this position.
第2步:使用HttpUtility.UrlEncode - this newtonsoft website link建议以下实施。
string json = @"[{ 'MyVar' : 'hello<script>bad script code</script>world' }]";
JArray readArray = JArray.Parse(json);
IList<KeyValue> blogPost = readArray.Select(p => new KeyValue {Key =HttpUtility.UrlEncode((string)p["MyVar"])}).ToList();