我们对代码进行了安全审核,他们提到我们的代码容易受到外部实体(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);

在审计报告中,他们说它失败是因为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);

但是我可以在这里看到Reader没有任何值可加载到xmlDoc(XmlDocument)中。
谁能帮我丢失东西的地方?
任何人的帮助表示赞赏!

最佳答案

使用通过XmlResolver属性提供的XmlDocument.XmlResolver解析外部资源。如果您的XML文档**不应包含任何外部资源**(例如DTD或模式),只需将此属性设置为null:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;
xmlDoc.LoadXml(OurOutputXMLString);

如果要过滤这些URL的来源(例如,仅允许某些域),只需从XmlUrlResolver派生您自己的类并覆盖ResolveUri()方法。您可以在此处检查URL并对其进行清理(例如,您只能在本地网络中或来自受信任来源的URL)。

例如:
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;
    }
}

其中IsUnsafeHost()是一个自定义函数,用于检查是否允许给定的主机。有关一些想法,请参见此处的this post。只需从null返回ResolveUri()即可保存您的代码免于这种攻击。如果允许使用URI,则可以简单地返回默认的XmlUrlResolver.ResolveUri()实现。

要使用它:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = new CustomUrlResolver();
xmlDoc.LoadXml(OurOutputXMLString);

有关如何解析XML外部资源的更多详细信息,请阅读MS Docs上的Resolving External Resources。如果您的代码比本示例要复杂,那么您绝对应该阅读Remarks section属性的XmlDocument.XmlResolver

关于c# - 如何防止XXE攻击(.net中的XmlDocument),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14230988/

10-11 13:51