CA3075: обработка небезопасных DTD

Свойство Значение
Идентификатор правила CA3075
Заголовок Обработка небезопасных DTD
Категория Безопасность
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 8 No

Причина

Если вы используете небезопасные экземпляры DtdProcessing или ссылаетесь на источники внешних сущностей, средство синтаксического анализа может принять недоверенные входные данные и раскрыть конфиденциальную информацию злоумышленникам.

Описание правила

DTD — это один из двух способов определения допустимости документа средством синтаксического анализа XML, как указано в стандарте XML 1.0 консорциума W3C. Это правило ищет свойства и экземпляры, в которых принимаются недоверенные данные, для предупреждения разработчиков о возможных угрозах раскрытия информации или атака типа отказ в обслуживании (DoS). Это правило активируется, если:

  • обработка DtdProcessing включена в экземпляре XmlReader , который разрешает внешние сущности XML с использованием XmlUrlResolver;

  • задано свойство InnerXml в XML;

  • для свойства DtdProcessing задано значение Parse;

  • недоверенные входные данные обрабатываются с помощью XmlResolver вместо XmlSecureResolver;

  • метод XmlReader.Create вызывается с небезопасным экземпляром XmlReaderSettings или без экземпляра;

  • XmlReader создается с небезопасными настройками или значениями по умолчанию.

В каждом из этих случаев результат одинаковый: содержимое из файловой системы или сетевых папок с компьютера, на котором обрабатывается XML, станет доступно злоумышленнику, или обработка DTD может использоваться для атак типа "отказ в обслуживании".

Устранение нарушений

  • Перехватывайте и обрабатывайте все исключения XmlTextReader соответствующим образом, чтобы не допустить раскрытия информации.

  • Используйте XmlSecureResolver, чтобы ограничить набор ресурсов, к которым может получить доступ XmlTextReader.

  • Не разрешайте XmlReader открывать какие-либо внешние ресурсы, установив для свойства XmlResolver значение NULL.

  • Убедитесь, что свойство DataViewManager.DataViewSettingCollectionString назначено из доверенного источника.

NET Framework 3.5 и предыдущие версии

  • Отключите обработку DTD при работе с недоверенными источниками, задав для свойства ProhibitDtd значение true.

  • Класс XmlTextReader содержит полное требование наследования доверия.

.NET Framework 4 и более поздних версий

  • Не включайте обработку DTD при работе с недоверенными источниками, задав для свойства XmlReaderSettings.DtdProcessing значение Prohibit или Ignore.

  • Убедитесь, что метод Load() принимает экземпляр XmlReader во всех случаях InnerXml.

Примечание.

Это правило может ложно срабатывать в некоторых допустимых экземплярах XmlSecureResolver.

Когда лучше отключить предупреждения

Отключайте правило этого предупреждения, только если уверены, что входные данные получены из доверенного источника.

Отключение предупреждений

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

#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. XmlReader из Create нормализует \r\n до \n в значениях XML, при этом XmlTextReader сохраняет последовательность \r\n.