C# 如何防止 XXE 攻击(.net 中的 XmlDocument)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14230988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to prevent XXE attack ( XmlDocument in .net)
提问by junni lomo
We had a security audit on our code, and they mentioned that our code is vulnerable to EXternal Entity (XXE) attack. I am using following code -
我们对我们的代码进行了安全审计,他们提到我们的代码容易受到外部实体 (XXE) 攻击。我正在使用以下代码 -
string OurOutputXMLString=
"<ce><input><transaction><length>00000</length><tran_type>Login</tran_type></transaction><user><user_id>ce_userid</user_id><subscriber_name>ce_subscribername</subscriber_name><subscriber_id>ce_subscriberid</subscriber_id><group_id>ce_groupid</group_id><permissions></permissions></user><consumer><login_details><username>UnitTester9</username><password>pDhE5AsKBHw85Sqgg6qdKQ==</password><pin>tOlkiae9epM=</pin></login_details></consumer></input></ce>"
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(OurOutputXMLString);
In Audit report they say that its failing because XML entity can contain URLs that can resolve outside of intended contronl. XML entity resolver will attempt to resolve and retrieve external references. If attacker-controlled XML can be submitted to one of these functions, then the attacker could gain access to information about an internal network, local filesystem, or other sensitive data. To avoid this i wrote the following code but it doesnt work.
在审计报告中,他们说它失败了,因为 XML 实体可以包含可以在预期控制之外解析的 URL。XML 实体解析器将尝试解析和检索外部引用。如果攻击者控制的 XML 可以提交给这些函数之一,那么攻击者就可以获得有关内部网络、本地文件系统或其他敏感数据的信息。为了避免这种情况,我编写了以下代码,但它不起作用。
MemoryStream stream =
new MemoryStream(System.Text.Encoding.Default.GetBytes(OurOutputXMLString));
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
settings.MaxCharactersFromEntities = 6000;
XmlReader reader = XmlReader.Create(stream, settings);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
but i can see here that reader does not have any value to load into xmlDoc(XmlDocument). Can anyone help where i am missing things? Anyone help is appreciated !
但我可以在这里看到 reader 没有任何值可以加载到 xmlDoc(XmlDocument) 中。任何人都可以帮助我丢失的东西吗?任何帮助表示赞赏!
采纳答案by Adriano Repetti
External resources are resolved using the XmlResolver
provided via XmlDocument.XmlResolver
property. If your XML documents **should not contain any external resource **(for example DTDs or schemas) simply set this property to null
:
使用XmlResolver
提供的 viaXmlDocument.XmlResolver
属性解析外部资源。如果您的 XML 文档 ** 不应包含任何外部资源 **(例如 DTD 或模式),只需将此属性设置为null
:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(OurOutputXMLString);
If you want to filter where these URLs come from (for example to allow only certain domains) just derive your own class from XmlUrlResolver
and override the ResolveUri()
method. There you can check what the URL is and sanitize it (for example you can allow only URLs within your local network or from trusted sources).
如果您想过滤这些 URL 的来源(例如只允许某些域),只需从中派生自己的类XmlUrlResolver
并覆盖该ResolveUri()
方法。在那里,您可以检查 URL 是什么并对其进行清理(例如,您只能允许本地网络中的 URL 或来自可信来源的 URL)。
For example:
例如:
class CustomUrlResovler : XmlUrlResolver
{
public override Uri ResolveUri(Uri baseUri, string relativeUri)
{
Uri uri = new Uri(baseUri, relativeUri);
if (IsUnsafeHost(uri.Host))
return null;
return base.ResolveUri(baseUri, relativeUri);
}
private bool IsUnsafeHost(string host)
{
return false;
}
}
Where IsUnsafeHost()
is a custom function that check if the given host is allowed or not. See this posthere on SO for few ideas. Just return null
from ResolveUri()
to saveyour code from this kind of attacks. In case the URI is allowed you can simply return the default XmlUrlResolver.ResolveUri()
implementation.
IsUnsafeHost()
检查给定主机是否被允许的自定义函数在哪里。有关一些想法,请参阅SO 上的这篇文章。只是返回null
从ResolveUri()
以保存从这种攻击代码。如果允许使用 URI,您可以简单地返回默认XmlUrlResolver.ResolveUri()
实现。
To use it:
要使用它:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = new CustomUrlResolver();
xmlDoc.LoadXml(OurOutputXMLString);
For more details about how XML external resources are resolved just read Resolving External Resourceson MS Docs. If your code is more complex than this example then you should definitely read Remarks sectionfor XmlDocument.XmlResolverproperty.
有关如何解析 XML 外部资源的更多详细信息,请阅读MS Docs 上的解析外部资源。如果你的代码是比这个例子更复杂,那么你一定要读备注部分用于XmlDocument.XmlResolver财产。
回答by mousetwentytwo
So its better to use
所以最好使用
new XmlDocument { XmlResolver = null };
Interestingly from .net 4.5.2 and 4.6, the default resolver behaves differently and does not use an XmlUrlResolver upfront implicitly to resolve any urls or locations as i seen.
有趣的是,从 .net 4.5.2 和 4.6 开始,默认解析器的行为有所不同,并且不会预先隐式地使用 XmlUrlResolver 来解析我所看到的任何 url 或位置。
//In pre 4.5.2 it is a security issue.
//In 4.5.2 it will not resolve any more the url references in dtd and such,
//Still better to avoid the below since it will trigger security warnings.
new XmlDocument();