问题描述
我正在开发一个使用 BinaryFormatter.Deserialize 的应用程序已经有一段时间了。我们最近运行了 CheckMarx 漏洞扫描,将其标记为问题。 Microsoft even calls it "dangerous"。序列化不是 CheckMarx 的标志,所以我打算保持原样,我需要保持与现有客户的兼容性,而不是彻底改变。
我在反序列化 ConcurrentDictionary
时遇到问题。
首先我尝试了 XmlSerializer
,但发现它不支持 IDictionary。
然后我尝试了 DataContractSerializer
,因为它确实支持字典,但也失败了。
CheckMarx 标记的漏洞方式
using (FileStream fs = new FileStream(_savePath,FileMode.Open,FileAccess.Read,FileShare.Read))
{
BinaryFormatter formatter = new BinaryFormatter();
fileCache = (ConcurrentDictionary<string,string>)formatter.Deserialize(fs);
}
我现在正在尝试什么
using (FileStream fs = new FileStream(_savePath,FileShare.Read))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(ConcurrentDictionary<string,string>));
ConcurrentDictionary<string,string> conDict;
//I tried this way,which Failed - "Unexpected end of file."
conDict = (ConcurrentDictionary<string,string>)serializer.Readobject(fs);
//I tried this way,which also Failed - "The data at the root level is invalid. Line 1,position 1."
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs,new XmlDictionaryReaderQuotas());
conDict = (ConcurrentDictionary<string,string>)serializer.Readobject(reader,true);
}
感谢您的任何建议。
解决方法
如果您至少不能远离 BinaryFormatter(这不是保护它的最佳方法,尤其是在您的应用程序是高风险的情况下)是设置 Binder 属性带有 SerializationBinder 的 BinaryFormatter:
using (FileStream fs = new FileStream(_savePath,FileMode.Open,FileAccess.Read,FileShare.Read))
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Binder = new DictionaryDeserializationBinder();
fileCache = (ConcurrentDictionary<string,string>)formatter.Deserialize(fs);
}
public class DictionaryDeserializationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName,string typeName)
{
if (typeName.Equals("XmlDictionaryReader")){
return typeof(XmlDictionaryReader);
}
return null;
}
}
上面的代码需要一些编辑,因为我不确定您想要反序列化并验证它是什么类型。还有一个假设是检查您传递到字典中的数据,而不仅仅是检查是否有危险的 .NET 类型产生