System.Xml 보안 고려 사항
업데이트: November 2007
다음 단원에서는 System.Xml 구성 요소로 작업할 때 발생할 수 있는 보안 문제 유형과 이러한 위협 요소를 완화하는 방법을 설명합니다.
참고: |
---|
System.Xml 구성 요소는 Microsoft .NET Framework 보안 시스템을 사용합니다. 이 항목에서는 XML 클래스가 특별히 처리하는 보안 문제만 다룹니다. 자세한 내용은 .NET Framework의 보안을 참조하십시오. |
XmlResolver 클래스
XmlReader 및 XmlReaderSettings 클래스
XmlTextReader 클래스
XslCompiledTransform 클래스
Document Object Model
XmlResolver 클래스
XmlResolver 클래스를 사용하여 리소스를 확인할 수 있습니다. 이 클래스를 사용하여 XML 문서를 로드하고 엔터티, DTD 또는 스키마와 같은 외부 리소스를 확인하며, 지시문을 가져오거나 포함할 수 있습니다. .NET Framework에는 XmlResolver 클래스의 두 가지 구현이 포함되어 있습니다.
XmlUrlResolver 클래스는 System.Xml 네임스페이스의 모든 클래스에 대한 기본 해결 프로그램입니다. file:// 및 http:// 프로토콜을 지원하고 WebRequest 클래스에서 요청합니다. 대부분의 경우, 응용 프로그램에서 사용해야 하는 XmlResolver 개체를 지정하지 않으면 XmlUrlResolver 개체가 사용자 자격 증명 없이, XML 리소스에 액세스하는 데 사용됩니다.
XmlSecureResolver 클래스를 사용하면 XmlResolver 개체를 래핑하고 소스로 사용하는 XmlResolver가 액세스하는 리소스를 제한하여 다른 XmlResolver 개체를 보호할 수 있습니다. 예를 들어, XmlSecureResolver 클래스는 특정 인터넷 사이트 또는 영역에 액세스하지 못하도록 할 수 있습니다.
XmlResolver 클래스를 사용할 때 다음 사항을 고려해야 합니다.
XmlResolver 개체에는 데이터에 액세스하고 데이터를 검색할 때 사용할 수 있는 사용자 자격 증명과 같은 중요한 정보가 포함될 수 있습니다. XmlResolver 개체를 캐시할 때는 주의해야 하며 신뢰할 수 없는 구성 요소는 XmlResolver 및 사용자 자격 증명을 사용하여 데이터에 액세스할 수 있으므로 XmlResolver 개체를 신뢰할 수 없는 구성 요소에 전달해서는 안 됩니다.
XmlResolver 클래스를 사용하는 클래스 속성을 디자인하는 경우 이 속성을 쓰기 전용 속성으로 정의해야 합니다. 이 속성을 사용하여 사용할 XmlResolver를 지정할 수 있지만 XmlResolver 개체를 반환할 수는 없습니다. 또한 신뢰할 수 없는 구성 요소에서 이 클래스를 사용할 수 있지만 XmlResolver 개체를 검색하거나 직접 사용할 수는 없습니다.
응용 프로그램이 신뢰할 수 없는 코드의 XmlResolver 개체를 허용하는 경우 GetEntity 메서드에 전달된 URI가 ResolveUri 메서드가 반환한 URI와 같다고 가정할 수 없습니다. XmlResolver 클래스에서 파생된 클래스는 GetEntity 메서드를 재정의하고 원래 URI에 포함된 데이터와 다른 데이터를 반환할 수 있습니다.
응용 프로그램에서는 읽는 바이트 수를 제한하는 래핑 구현 IStream을 구현하여 GetEntity 메서드에 대한 메모리 서비스 거부(Denial of Service) 위협 요소를 완화할 수 있습니다. 그러면 악성 코드가 무한 바이트 스트림을 GetEntity 메서드에 전달하려고 시도하는 경우 이로부터 보호할 수 있습니다.
XmlReader 및 XmlReaderSettings 클래스
사실상 모든 System.Xml 구성 요소는 구문 분석하는 XML의 최상위 개념을 바탕으로 만들어졌습니다. 예를 들어, XmlDocument 클래스는 XmlReader 클래스를 사용하여 문서를 구문 분석하고 XML 문서의 메모리 내 표현을 만듭니다.
Create 메서드를 사용하여 XmlReader 개체를 만드는 것이 좋습니다. XmlReaderSettings 클래스는 XmlReader 개체에서 사용할 기능 집합을 지정합니다.
문서 및 엔터티 확장 크기 제한
XmlReader를 사용하는 응용 프로그램의 메모리 사용은 구문 분석된 XML 문서 크기와 상관 관계가 있습니다. 서비스 거부 공격의 한 예는 구문 분석하기에는 너무 큰 XML 문서를 제출하는 경우입니다.
XmlReader를 사용할 때 MaxCharactersInDocument 속성을 설정하여 구문 분석될 수 있는 문서 크기를 제한할 수 있습니다. MaxCharactersFromEntities 속성을 설정하여 확장 엔터티의 결과인 문자 수를 제한할 수 있습니다. 이러한 속성 설정 예제를 보려면 적절한 참조 항목을 참고하십시오.
DTD 처리
DTD를 처리할 때 DoS 상황이 발생할 수 있습니다. 예를 들어, 처리하는 데 엄청난 시간이 걸릴 수 있는 중첩된 엔터티 또는 복합 내용 모델이 DTD에 포함될 수 있습니다.
DTD 처리는 기본적으로 비활성화되어 있습니다. XmlReader에서 DTD 데이터가 나타나면 XmlException이 throw됩니다.
스키마 처리
XmlReaderSettings 개체의 ProcessInlineSchema 및 ProcessSchemaLocation 유효성 검사 플래그는 기본적으로 설정되지 않습니다. 그러므로 신뢰할 수 없는 소스의 XML 데이터를 처리할 때 스키마 기반 공격으로부터 XmlReader를 보호할 수 있습니다. 이 플래그를 설정하면 XmlReaderSettings 개체의 XmlResolver를 사용하여 XmlReader에서 인스턴스 문서에 나타난 스키마 위치를 확인할 수 있습니다. XmlResolver 속성을 null로 설정하면 ProcessInlineSchema 및 ProcessSchemaLocation 유효성 검사 플래그를 설정한 경우에도 스키마 위치를 확인할 수 없습니다.
유효성을 검사하는 동안 추가된 스키마는 새 형식을 추가하며 유효성을 검사하는 문서의 유효성 검사 결과를 변경할 수 있습니다. 결과적으로 외부 스키마는 신뢰할 수 있는 소스에서만 확인해야 합니다.
고가용성 시나리오에서 문서 대부분에 identity 제약 조건이 있는 스키마에 대해 신뢰할 수 없는 큰 XML 문서의 유효성을 검사할 경우 기본적으로 활성화되어 있는 ProcessIdentityConstraints 플래그를 비활성화하는 것이 좋습니다.
외부 리소스
XML 데이터에는 스키마 파일과 같은 외부 리소스에 대한 참조가 포함될 수 있습니다. 기본적으로 외부 리소스는 사용자 자격 증명 없이 XmlUrlResolver 개체를 사용하여 확인됩니다. 그러므로 기본적으로 자격 증명이 필요하지 않은 모든 위치에 액세스할 수 있습니다. 다음 중 하나를 수행하여 이 추가 기능을 보호할 수 있습니다.
XmlReaderSettings.XmlResolver 속성을 XmlSecureResolver 개체로 설정하여 XmlReader가 액세스할 수 있는 리소스를 제한합니다.
XmlReaderSettings.XmlResolver 속성을 null로 설정하여 XmlReader가 모든 외부 리소스를 열 수 없도록 하십시오.
XmlReaderSettings 개체 공유
XmlReaderSettings 개체에는 사용자 자격 증명과 같은 중요한 정보가 포함될 수 있습니다. 신뢰할 수 없는 구성 요소는 XmlReaderSettings 개체 및 해당 사용자 자격 증명을 사용하여 XmlReader 개체를 만들어 데이터를 읽을 수 있습니다. XmlReaderSettings 개체를 캐시하거나 한 구성 요소에서 다른 구성 요소로 XmlReaderSettings 개체를 전송할 때는 주의해야 합니다.
지원 구성 요소
- 신뢰할 수 없는 소스로부터 NameTable, XmlNamespaceManager 및 XmlResolver 개체 등의 지원 구성 요소를 받지 마십시오.
데이터 처리
XML 데이터에는 처리하는 데 시간이 많이 걸리는 수많은 특성, 네임스페이스 선언, 중첩된 요소 등이 포함될 수 있습니다.
사용되는 입력 크기를 제한하는 사용자 지정 IStream 구현을 만들고 이를 XmlReader 클래스에 제공할 수 있습니다.
ReadValueChunk 메서드를 사용하여 많은 데이터 스트림을 처리합니다. 이 메서드는 전체 값에 대한 단일 문자열을 할당하는 대신 한 번에 적은 수의 문자를 읽습니다.
XmlTextReader 클래스
XmlTextReader 클래스는 XmlReader 클래스의 레거시 구현입니다.
DTD 처리
DTD 처리는 기본적으로 활성화되어 있습니다. DTD 처리를 비활성화하려면 ProhibitDtd 속성을 true로 설정합니다.
엔터티 처리
기본적으로 일반 엔터티는 확장되지 않습니다. ResolveEntity 메서드를 호출해야 일반 엔터티가 확장됩니다.
외부 리소스
XML 데이터에는 DTD 참조와 같은 외부 리소스에 대한 참조가 포함될 수 있습니다. 기본적으로 외부 리소스는 사용자 자격 증명 없이 XmlUrlResolver 개체를 사용하여 확인됩니다.
다음 중 하나를 수행하여 이 추가 기능을 보호할 수 있습니다.
XmlResolver 속성을 XmlSecureResolver 개체로 설정하여 XmlTextReader가 액세스할 수 있는 리소스를 제한합니다.
XmlResolver 속성을 null로 설정하여 XmlTextReader가 모든 외부 리소스를 열 수 없도록 하십시오.
XslCompiledTransform 클래스
XslCompiledTransform 클래스는 XSLT 1.0 구문을 지원하는 XSLT 프로세서입니다. 이 클래스를 사용하면 XSLT 스타일시트를 사용하여 XML 데이터를 변환할 수 있습니다.
외부 리소스
스타일시트에는 xsl:import 또는 xsl:include 요소나 document() 함수와 같은 외부 리소스에 대한 참조가 포함될 수 있습니다.
기본적으로 XslCompiledTransform 클래스는 xsl:import 또는 xsl:include 요소를 지원합니다. XslCompiledTransform 클래스는 기본적으로 document() 함수를 지원하지 않습니다. XsltSettings 클래스를 사용하여 document() 함수를 활성화할 수 있습니다.
Load 및 Transform 메서드는 XmlResolver 개체를 해당 인수의 하나로 사용하는 오버로드를 포함합니다. XmlResolver가 지정되지 않을 경우 기본 XmlUrlResolver가 자격 증명 없이 사용됩니다.
다음 중 하나를 수행하여 외부 리소스에 액세스하는 방법을 제어할 수 있습니다.
XmlSecureResolver 개체를 사용하여 XSLT 프로세스가 액세스할 수 있는 리소스를 제한합니다.
null을 XmlResolver 인수에 전달하여 XSLT 프로세스에서 외부 리소스를 열 수 없도록 설정합니다.
스크립트 블록
XslCompiledTransform 클래스는 기본적으로 스크립트 블록을 지원하지 않습니다. 스크립트 블록을 사용하려면 XsltSettings 클래스를 사용합니다. XSLT 스크립트는 스크립트 지원이 필요하거나 완전히 신뢰할 수 있는 환경에서 작업하는 경우에만 활성화해야 합니다.
확장 개체
확장 개체는 프로그래밍 기능을 XSLT 변환에 추가합니다. 이 기능은 기본적으로 활성화되어 있습니다. 확장 개체를 Transform 메서드에 전달하면 XSLT 변환에 사용됩니다.
문서 개체 모델
DOM(문서 개체 모델)은 메모리에 있는 모든 데이터를 캐시하기 때문에 신뢰할 수 없는 데이터로 작업하면서 서비스 거부(Denial of Service) 공격에 대해 염려하는 경우 쿼리, 편집, 문서 간 하위 트리 이동, DOM 개체 저장 등의 DOM 작업은 수행하지 않는 것이 좋습니다. 또는 DOM으로 읽어올 수 있는 데이터 양을 제한할 수 있습니다. 이렇게 하려면 사용되는 입력 크기를 제한하는 사용자 지정 스트림 구현을 만들고 이를 사용하여 DOM 개체를 로드합니다.
XmlDocument 개체에는 포함된 XmlResolver 개체의 사용자 자격 증명과 같은 중요한 정보가 포함될 수 있습니다. XmlDocument.XmlResolver 속성을 사용자 자격 증명이 있는 XmlResolver 개체로 설정한 경우 XmlDocument 개체를 캐시하거나 신뢰할 수 없는 구성 요소로 전달해서는 안 됩니다. 신뢰할 수 없는 구성 요소가 DOM 개체 및 포함된 XmlResolver 사용자 자격 증명을 사용하여 데이터에 액세스하고 데이터를 로드할 수 있기 때문입니다.