2013-01-09 10 views
20

Mieliśmy audyt bezpieczeństwa na naszym kodzie, i wspomniał, że nasz kod jest podatny na zewnętrzne jednostki (XXe) ataku. Używam następujący kod -Jak zapobiec atak XXe (XmlDocument w .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); 

W raporcie Audytu mówią, że jego wadą, ponieważ jednostka XML może zawierać adresów URL, które można rozwiązać poza zamierzonym contronl. Narzędzie do rozstrzygania encji XML spróbuje rozwiązać i pobrać odnośniki zewnętrzne. Jeśli atakujący sterowany XML można składać do jednej z tych funkcji, to osobie atakującej uzyskanie dostępu do informacji o sieci wewnętrznej, lokalnego systemu plików lub innych danych wrażliwych. Aby tego uniknąć i napisał następujący kod, ale nie robi praca.

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

ale widzę tutaj, że czytnik nie ma żadnej wartości do załadowania do xmlDoc (XmlDocument). Czy ktoś może pomóc, gdzie brakuje rzeczy? Każda pomoc jest doceniana!

+4

Jeśli masz pewność, że nie zamierzasz korzystać z zasobów zewnętrznych, możesz kontrolować poświadczenia używane przez XMLResolver XmlDocument. Zobacz przykład: http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.xmlresolver.aspx. W tym przypadku można ustawić poświadczenia XmlResolver na konto, które ma tylko ograniczone prawa dostępu, więc każda próba pobrania zasobów może być kontrolowana za pomocą uprawnień NT. – dash

+2

W rzeczywistości jest to bardzo przydatny artykuł MSDN, który odpowiada na twoje pytanie: http://msdn.microsoft.com/en-us/magazine/ee335713.aspx – dash

Odpowiedz

28

zasoby zewnętrzne są rozwiązywane przy użyciu XmlResolver dostarczonych przez XmlDocument.XmlResolver nieruchomości. Jeśli dokumenty XML ** nie powinny zawierać żadnych zasobów zewnętrznych ** (np DTD lub schematów) po prostu ustawić tę właściwość do null:

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

Jeśli chcesz filtrować adresy gdzie te pochodzą z (na przykład w celu umożliwienia tylko niektóre domeny) po prostu czerpią swoją klasę od XmlUrlResolver i zastąpić metodę ResolveUri(). Tam możesz sprawdzić, jaki jest adres URL i oczyścić go (na przykład możesz zezwolić tylko na adresy URL w Twojej sieci lokalnej lub zaufanych źródłach).

Na przykład:

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

Gdzie IsUnsafeHost() ma funkcję niestandardową, które sprawdzają, czy dany host jest dozwolone, czy nie. Zobacz this post tutaj na SO dla kilku pomysłów. Wystarczy wrócić null z ResolveUri() do oszczędzania kodu przed tego rodzaju atakami. Jeśli identyfikator URI jest dozwolony, możesz po prostu zwrócić domyślną implementację XmlUrlResolver.ResolveUri().

Aby go użyć:

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

Aby uzyskać więcej informacji o tym, jak XML zasoby zewnętrzne są rozwiązane tylko czytać Resolving External Resources na MS Docs. Jeśli twój kod jest bardziej złożony niż ten przykład, powinieneś koniecznie przeczytać Remarks section dla właściwości XmlDocument.XmlResolver.

+0

Wow! Dzięki za to Adriano i to zadziałało. Dziękuję Dash za informację. –

2

więc jej lepiej użyć

new XmlDocument { XmlResolver = null }; 

ciekawe z .NET 4.6 i 4.5.2, domyślny rezolwer zachowuje się inaczej i nie używać XmlUrlResolver upfront niejawnie rozwiązać wszelkie adresy URL lub lokalizacje jak widziałem.

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