2013-01-09 11 views
20

Wir haben eine Sicherheitsüberprüfung für unseren Code durchgeführt, und sie haben erwähnt, dass unser Code anfällig für Angriffe durch externe Entitäten (XXE) ist. Ich verwende folgenden Code -So verhindern Sie den XXE-Angriff (XmlDocument in .net)

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-Bericht sagen sie, dass ihr Versagen, weil XML-Entity-URLs enthalten, die außerhalb der beabsichtigten contronl auflösen kann. Der XML-Entitätsresolver versucht, externe Referenzen aufzulösen und abzurufen. Wenn Angreifer-gesteuertes XML an eine dieser Funktionen übergeben werden kann, kann der Angreifer Zugriff auf Informationen über ein internes Netzwerk, ein lokales Dateisystem oder andere vertrauliche Daten erhalten. Um dies zu vermeiden, habe ich den folgenden Code geschrieben, aber es funktioniert nicht.

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

, aber ich kann hier sehen, dass Leser keinen Wert haben in xmlDoc zu laden (XmlDocument). Kann mir jemand helfen, wo ich Dinge vermisse? Wer Hilfe ist, wird geschätzt!

+4

Wenn Sie sicher sind, dass Sie keine externen Ressourcen verwenden, können Sie die Anmeldeinformationen, die der XmlDocument XMLResolver verwendet, kontrollieren. Ein Beispiel finden Sie in http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.xmlresolver.aspx. In diesem Fall könnten Sie die Anmeldeinformationen des XmlResolvers auf ein Konto mit eingeschränkten Zugriffsrechten festlegen, sodass jeder Versuch, Ressourcen abzurufen, über NT-Berechtigungen gesteuert werden kann. – dash

+2

In der Tat ist hier ein sehr nützlicher MSDN-Artikel, der Ihre Frage anspricht: http://msdn.microsoft.com/en-us/magazine/ee335713.aspx – dash

Antwort

28

Externe Ressourcen werden mithilfe der XmlResolver-Komponente, die über die XmlDocument.XmlResolver-Eigenschaft bereitgestellt wird, aufgelöst. Wenn Ihre XML-Dokumente ** keine externe Ressource ** (zB DTDs oder Schemata) enthalten sollte einfach diese Eigenschaft auf null gesetzt:

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

Wenn Sie filtern möchten, wo diese URLs aus (zum Beispiel kommen zu lassen nur bestimmte Domains) leiten Sie einfach Ihre eigene Klasse von XmlUrlResolver ab und überschreiben Sie die ResolveUri() Methode. Dort können Sie überprüfen, was die URL ist, und sie bereinigen (z. B. können Sie nur URLs in Ihrem lokalen Netzwerk oder aus vertrauenswürdigen Quellen zulassen).

Zum Beispiel:

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

Wo IsUnsafeHost() eine benutzerdefinierte Funktion ist, die überprüfen, ob die angegebene Host erlaubt ist oder nicht. Siehe this post hier auf SO für einige Ideen. Geben Sie einfach null von ResolveUri() bis speichern Ihren Code von dieser Art von Angriffen. Wenn der URI erlaubt ist, können Sie einfach die Standard-Implementierung XmlUrlResolver.ResolveUri() zurückgeben.

es zu benutzen:

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

Weitere Informationen darüber, wie XML externe Ressourcen gelöst werden gerade gelesen Resolving External Resources auf MS Docs. Wenn Ihr Code komplexer als dieses Beispiel ist, sollten Sie auf jeden Fall Remarks section für XmlDocument.XmlResolver Eigenschaft lesen.

+0

Wow! Danke Adriano dafür und das hat für mich funktioniert. Danke Dash für die Info. –

2

So ist es besser,

new XmlDocument { XmlResolver = null }; 

Interessanter von .net 4.5.2 und 4.6, verwenden Sie die Standard-Resolver verhält sich anders und verwenden keine XmlUrlResolver Voraus implizit alle URLs oder Standorte zu lösen, wie ich gesehen.

//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(); 
Verwandte Themen