C# 解析加载读取XML文件的正确姿势
危险写法
在C#加载XML文件时,我们常用的做法是:
C# 全选
XmlDocument doc = new XmlDocument()
doc.LoadXml(xmlFileName)
如果你要这样写,就会引发一个 XML外部实体注入 的漏洞
一级类:代码注入
二级类:XML外部实体注入
漏洞详细信息
在XML1.0标准里,XML文档结构里定义了实体(entity)这个概念。实体可以通过预定义在文档中调用,实体的标识符可访问本地或远程内容。如果在这个过程中引入了“污染”源,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
**例如:**
XML 全选
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE a [
<!ELEMENT a ANY >
<!ENTITY xxe SYSTEM "file:///c:/Windows/win.ini" >]><a>&xxe;</a>
如果 XML 解析器尝试使用 c:/Windows/win.ini 系统文件中的内容来替代实体,则此示例会暴露该文件中的内容。
修复建议
预防XXE攻击的最佳方式就是禁用XML实体解析,方法是:将DtdProcessing设置为DtdProcessing.
Prohibit来禁用inline DTD,或将XmlReaderSettings.XmlResolver属性设置为null来禁用XML Entity解析:
C# 全选
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing =DtdProcessing.Prohibit;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);
如果必须在应用程序中处理外部实体,可以创建一个自定义XmlResolver:
设置请求超时,预防无限延迟攻击;
限制将检索的数据量;
限制 XmlResolver 检索本地主机上的资源。
详细代码可参考: https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
实例
xml转换为json字符串
C# 全选
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WindowsFormsApp1.xml"), settings);
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(reader);
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post 张国生