CA3075: 안전하지 않은 DTD 처리

속성 값
규칙 ID CA3075
제목 DTD 처리가 안전하지 않습니다.
범주 보안
수정 사항이 문제를 일으키는지 아닌지 주요 변경 아님
.NET 10에서 기본적으로 사용하도록 설정 아니요
적용 가능한 언어 C# 및 Visual Basic

원인

안전하지 않은 DtdProcessing 인스턴스를 사용하거나 외부 엔터티 소스를 참조하면 파서는 신뢰할 수 없는 입력을 허용하고 공격자에게 중요 한 정보를 공개할 수 있습니다.

규칙 설명

DTD(문서 종류 정의) 는 XML 파서가 W3C(World Wide Web Consortium) XML(Extensible Markup Language) 1.0에 정의된 대로 문서의 유효성을 확인할 수 있는 두 가지 방법 중 하나입니다. 이 규칙은 신뢰할 수 없는 데이터가 허용되는 속성 및 규칙을 찾아 잠재적인 정보 공개 위협 또는 DoS(서비스 거부) 공격에 대해 개발자에게 경고합니다. 다음 경우에 이 규칙이 트리거됩니다.

이러한 경우 모두 결과는 동일합니다. 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

파일, 폴더 또는 프로젝트에 대한 규칙을 사용하지 않도록 설정하려면 구성 파일에서 심각도를 로 설정합니다.

[*.{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와 동작 차이가 있습니다. XmlReader의 Create는 \r\n을 XML 값의 \n으로 정규화하고 XmlTextReader는 \r\n 시퀀스를 유지합니다.