2013-01-09 1 views
20

우리는 우리의 코드에 보안 감사가 있고, 그들은 우리의 코드가 외부 엔티티 (결선도) 공격에 취약 언급을 방지하는 방법. 감사 보고서에서결선도 공격 (.NET에서을 XmlDocument)

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 엔티티가 외부 구성 contronl의 해결할 수있는 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); 

하지만 독자는 xmlDoc (XmlDocument)에로드 할 값이 없음을 알 수 있습니다. 내가 누락 된 부분을 도와 줄 사람이 있습니까? 누구나 도움을 주실 수 있습니다!

+4

외부 리소스를 사용하지 않을 것이라 확신하는 경우 XmlDocument의 XMLResolver가 사용하는 자격 증명을 제어 할 수 있습니다. 예제는 http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.xmlresolver.aspx를 참조하십시오. 이 경우 XmlResolver의 자격 증명을 제한된 액세스 권한을 가진 계정으로 설정할 수 있으므로 리소스를 검색하려는 모든 시도는 NT 권한을 통해 제어 할 수 있습니다. – dash

+2

사실, 다음은 질문에 대답하는 매우 유용한 MSDN 문서입니다. http://msdn.microsoft.com/en-us/magazine/ee335713.aspx – dash

답변

28

외부 자원 XmlDocument.XmlResolver 속성을 통해 제공되는 XmlResolver 사용하여 해결됩니다. XML 문서가 ** ** (예를 들어, DTD를 또는 스키마에 대한) 외부 자원을 포함 할 수 없습니다 경우 단순히 null이 속성을 설정합니다

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

당신이이 URL을 허용 (예를 들어 어디에서 온 필터링하려면 특정 도메인 만)은 XmlUrlResolver에서 자신의 클래스를 파생하고 ResolveUri() 메서드를 재정의합니다. 여기에서 URL이 무엇인지 확인하고 위생 처리 할 수 ​​있습니다 (예 : 로컬 네트워크 또는 신뢰할 수있는 출처에서 URL 만 허용 할 수 있음). 예를 들어

:

IsUnsafeHost() 지정된 호스트가 허용되거나되지 않은 경우 확인 사용자 정의 기능입니다
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; 
    } 
} 

. 아이디어가 거의 없으므로 여기에 this post을 참조하십시오. 그냥 공격의이 종류에서 저장 코드에 ResolveUri()에서 null을 반환합니다. URI가 허용되는 경우 기본 XmlUrlResolver.ResolveUri() 구현을 간단히 반환 할 수 있습니다.

이 기능을 사용하려면

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

를 XML 외부 리소스가 바로 해결 MS 문서에 Resolving External Resources을 읽는 방법에 대한 자세한 내용은. 코드가이 예제보다 복잡하다면 XmlDocument.XmlResolver 속성에 대해 Remarks section을 확실히 읽어야합니다.

+0

와우! 이 점에 대해 Adriano에게 감사 드리며 이것은 나를 위해 일했습니다. 정보를 주셔서 감사합니다. –

2

그래서 그것의 더 나은 기본 해결이 다르게 작동하고 내가 볼 때 어떤 URL 또는 위치를 확인할 암시 적 선행 XmlUrlResolver를 사용하지 않는, .NET 4.5.2 및 4.6에서 흥미롭게

new XmlDocument { XmlResolver = null }; 

를 사용합니다.

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