CA3075: 안전하지 않은 DTD 처리
속성 | 값 |
---|---|
규칙 ID | CA3075 |
제목 | DTD 처리가 안전하지 않습니다. |
범주 | 보안 |
수정 사항이 주요 변경인지 여부 | 주요 변경 아님 |
.NET 9에서 기본적으로 사용 | 아니요 |
원인
안전하지 않은 DtdProcessing 인스턴스를 사용하거나 외부 엔터티 소스를 참조하면 파서는 신뢰할 수 없는 입력을 허용하고 공격자에게 중요 한 정보를 공개할 수 있습니다.
규칙 설명
DTD(문서 종류 정의) 는 XML 파서가 W3C(World Wide Web Consortium) XML(Extensible Markup Language) 1.0에 정의된 대로 문서의 유효성을 확인할 수 있는 두 가지 방법 중 하나입니다. 이 규칙은 신뢰할 수 없는 데이터가 허용되는 속성 및 규칙을 찾아 잠재적인 정보 공개 위협 또는 DoS(서비스 거부) 공격에 대해 개발자에게 경고합니다. 다음 경우에 이 규칙이 트리거됩니다.
XmlReader 를 사용하여 외부 XML 엔터티를 확인하는 XmlUrlResolver인스턴스에서 DtdProcessing이 사용되도록 설정된 경우
XML의 InnerXml 속성이 설정된 경우
DtdProcessing 속성이 Parse로 설정된 경우
신뢰할 수 없는 입력이 XmlSecureResolver 대신 XmlResolver를 사용하여 처리되는 경우
XmlReader.Create 메서드가 안전하지 않은 XmlReaderSettings 인스턴스를 사용하거나 인스턴스 없이 호출되는 경우
안전하지 않은 기본 설정 또는 값을 사용하여 XmlReader를 만든 경우
이러한 경우 모두 결과는 동일합니다. XML이 처리되는 머신의 파일 시스템 또는 네트워크 공유의 내용이 공격자에게 노출되거나 DTD 처리를 DoS 벡터로 사용할 수 있습니다.
위반 문제를 해결하는 방법
모든 XmlTextReader 예외를 catch하고 적절히 처리하여 경로 정보가 공개되지 않도록 합니다.
XmlSecureResolver를 사용하여 XmlTextReader에서 액세스할 수 있는 리소스를 제한합니다.
XmlReader 속성을 XmlResolver null 로 설정하여가 외부 리소스를 열 수 없도록 합니다.
DataViewManager.DataViewSettingCollectionString 속성이 신뢰할 수 있는 소스에서 할당되었는지 확인합니다.
.NET Framework 3.5 이전 버전
ProhibitDtd 속성을 true로 설정하여 신뢰할 수 없는 소스를 처리하는 경우 DTD 처리를 사용하지 않도록 설정합니다.
XmlTextReader 클래스에는 완전 신뢰 상속 요청이 있습니다.
.NET Framework 4 이상
XmlReaderSettings.DtdProcessing 속성을 Prohibit 또는 Ignore로 설정하여 신뢰할 수 없는 소스를 처리하는 경우 DtdProcessing을 사용하도록 설정하지 않습니다.
Load() 메서드가 모든 InnerXml 경우에서 XmlReader 인스턴스를 사용하는지 확인합니다.
참고 항목
이 규칙은 일부 유효한 XmlSecureResolver 인스턴스에 대해 가양성(false positive)을 보고할 수 있습니다.
경고를 표시하지 않는 경우
입력 출처를 신뢰할 수 있는지 확신할 수 없으면 이 경고의 규칙이 표시되지 않도록 설정하지 않도록 합니다.
경고 표시 안 함
단일 위반만 표시하지 않으려면 원본 파일에 전처리기 지시문을 추가하여 규칙을 사용하지 않도록 설정한 후 다시 사용하도록 설정합니다.
#pragma warning disable CA3075
// The code that's violating the rule is on this line.
#pragma warning restore CA3075
파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 구성 파일에서 심각도를 none
으로 설정합니다.
[*.{cs,vb}]
dotnet_diagnostic.CA3075.severity = none
자세한 내용은 방법: 코드 분석 경고 표시 안 함을 참조하세요.
의사 코드 예제
위반 1
using System.IO;
using System.Xml.Schema;
class TestClass
{
public XmlSchema Test
{
get
{
var src = "";
TextReader tr = new StreamReader(src);
XmlSchema schema = XmlSchema.Read(tr, null); // warn
return schema;
}
}
}
솔루션 1
using System.IO;
using System.Xml;
using System.Xml.Schema;
class TestClass
{
public XmlSchema Test
{
get
{
var src = "";
TextReader tr = new StreamReader(src);
XmlReader reader = XmlReader.Create(tr, new XmlReaderSettings() { XmlResolver = null });
XmlSchema schema = XmlSchema.Read(reader , null);
return schema;
}
}
}
위반 2
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public XmlReaderSettings settings = new XmlReaderSettings();
public void TestMethod(string path)
{
var reader = XmlReader.Create(path, settings); // warn
}
}
}
해결 방법 2
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public XmlReaderSettings settings = new XmlReaderSettings()
{
DtdProcessing = DtdProcessing.Prohibit
};
public void TestMethod(string path)
{
var reader = XmlReader.Create(path, settings);
}
}
}
위반 3
using System.Xml;
namespace TestNamespace
{
public class DoNotUseSetInnerXml
{
public void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument() { XmlResolver = null };
doc.InnerXml = xml; // warn
}
}
}
using System.Xml;
namespace TestNamespace
{
public class DoNotUseLoadXml
{
public void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument(){ XmlResolver = null };
doc.LoadXml(xml); // warn
}
}
}
솔루션 3
using System.Xml;
public static void TestMethod(string xml)
{
XmlDocument doc = new XmlDocument() { XmlResolver = null };
System.IO.StringReader sreader = new System.IO.StringReader(xml);
XmlReader reader = XmlReader.Create(sreader, new XmlReaderSettings() { XmlResolver = null });
doc.Load(reader);
}
위반 4
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace TestNamespace
{
public class UseXmlReaderForDeserialize
{
public void TestMethod(Stream stream)
{
XmlSerializer serializer = new XmlSerializer(typeof(UseXmlReaderForDeserialize));
serializer.Deserialize(stream); // warn
}
}
}
솔루션 4
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace TestNamespace
{
public class UseXmlReaderForDeserialize
{
public void TestMethod(Stream stream)
{
XmlSerializer serializer = new XmlSerializer(typeof(UseXmlReaderForDeserialize));
XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings() { XmlResolver = null });
serializer.Deserialize(reader );
}
}
}
위반 5
using System.Xml;
using System.Xml.XPath;
namespace TestNamespace
{
public class UseXmlReaderForXPathDocument
{
public void TestMethod(string path)
{
XPathDocument doc = new XPathDocument(path); // warn
}
}
}
해결 방법 5
using System.Xml;
using System.Xml.XPath;
namespace TestNamespace
{
public class UseXmlReaderForXPathDocument
{
public void TestMethod(string path)
{
XmlReader reader = XmlReader.Create(path, new XmlReaderSettings() { XmlResolver = null });
XPathDocument doc = new XPathDocument(reader);
}
}
}
위반 6
using System.Xml;
namespace TestNamespace
{
class TestClass
{
public XmlDocument doc = new XmlDocument() { XmlResolver = new XmlUrlResolver() };
}
}
해결 방법 6
using System.Xml;
namespace TestNamespace
{
class TestClass
{
public XmlDocument doc = new XmlDocument() { XmlResolver = null }; // or set to a XmlSecureResolver instance
}
}
위반 7
using System.Xml;
namespace TestNamespace
{
class TestClass
{
private static void TestMethod()
{
var reader = XmlTextReader.Create(""doc.xml""); //warn
}
}
}
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public void TestMethod(string path)
{
try {
XmlTextReader reader = new XmlTextReader(path); // warn
}
catch { throw ; }
finally {}
}
}
}
해결 방법 7
using System.Xml;
namespace TestNamespace
{
public class TestClass
{
public void TestMethod(string path)
{
XmlReaderSettings settings = new XmlReaderSettings() { XmlResolver = null };
XmlReader reader = XmlReader.Create(path, settings);
}
}
}
참고 항목
XmlReader.Create는 XmlReader 인스턴스를 만드는 데 권장되는 방법이지만 XmlTextReader와 동작 차이가 있습니다. Create의 XmlReader는 \r\n
을 XML 값의 \n
으로 정규화하고 XmlTextReader는 \r\n
시퀀스를 유지합니다.
.NET