更改BinaryFormatter.反序列化为并发字典的DataContractSerializer



我正在开发一个使用BinaryFormatter.Deserialize的应用程序,该应用程序已经存在一段时间了。我们最近运行了CheckMarx漏洞扫描,将其标记为问题。微软甚至称之为";危险";。CheckMarx没有标记序列化,所以我计划保持原样,并且我需要保持与现有客户的兼容性,而不是彻底改变事情。

我在对ConcurrentDictionary进行反序列化时遇到问题。首先我尝试了XmlSerializer,但发现它不支持IDictionary。然后我尝试了DataContractSerializer,因为它确实支持Dictionary,但也失败了。

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, FileMode.Open, FileAccess.Read, 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(不是保护它的最佳方法,尤其是当您的应用程序是高风险的时(,请使用SerializationBinder:设置BinaryFormater的Binder属性

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;
}
}

上面的代码需要一些编辑,因为我不太确定你想反序列化并验证它的类型。还有一种假设是,对传递到Dictionary中的数据进行检查,而不仅仅是检查是否有危险的.NET类型来生成

最新更新