不受信任数据的反序列化¶
ID: cs/unsafe-deserialization-untrusted-input
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-502
Query suites:
- csharp-code-scanning.qls
- csharp-security-extended.qls
- csharp-security-and-quality.qls
从不受信任的输入反序列化对象可能会导致安全问题,例如拒绝服务或远程代码执行。
建议¶
避免从不受信任的来源反序列化对象,如果无法避免,请确保使用安全的反序列化框架。
示例¶
在本例中,使用带有简单类型解析器的 JavaScriptSerializer
反序列化来自 HTML 文本框的文本。使用类型解析器意味着可能会执行任意代码。
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
class Bad
{
public static object Deserialize(TextBox textBox)
{
JavaScriptSerializer sr = new JavaScriptSerializer(new SimpleTypeResolver());
// BAD
return sr.DeserializeObject(textBox.Text);
}
}
要修复此特定漏洞,我们避免使用类型解析器。在其他情况下,可能需要使用不同的反序列化框架。
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
class Good
{
public static object Deserialize(TextBox textBox)
{
JavaScriptSerializer sr = new JavaScriptSerializer();
// GOOD: no unsafe type resolver
return sr.DeserializeObject(textBox.Text);
}
}
在以下示例中,使用已知在用户提供类型的情况下易受攻击的 DataContractJsonSerializer
反序列化可能不受信任的流和类型。
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class BadDataContractJsonSerializer
{
public static object Deserialize(string type, Stream s)
{
// BAD: stream and type are potentially untrusted
var ds = new DataContractJsonSerializer(Type.GetType(type));
return ds.ReadObject(s);
}
}
为了修复此特定漏洞,我们使用了硬编码的普通旧 CLR 对象(POCO)类型。在其他情况下,可能需要使用不同的反序列化框架。
using System.Runtime.Serialization.Json;
using System.IO;
using System;
class Poco
{
public int Count;
public string Comment;
}
class GoodDataContractJsonSerializer
{
public static Poco Deserialize(Stream s)
{
// GOOD: while stream is potentially untrusted, the instantiated type is hardcoded
var ds = new DataContractJsonSerializer(typeof(Poco));
return (Poco)ds.ReadObject(s);
}
}