CA3075: Procesamiento no seguro de DTD

Propiedad Value
Identificador de la regla CA3075
Título Procesamiento no seguro de DTD
Categoría Seguridad
La corrección interrumpe o no interrumpe Poco problemático
Habilitado de forma predeterminada en .NET 8 No

Causa

Si usa instancias de DtdProcessing no seguras o hace referencia a orígenes de entidades externas, el analizador podría aceptar entradas que no sean de confianza y revelar información confidencial a atacantes.

Descripción de la regla

Una definición de tipo de documento (DTD) es una de las dos formas que tiene un analizador XML para determinar la validez de un documento, como se define en el lenguaje de marcado extensible (XML) 1.0 de World Wide Web Consortium (W3C). Esta regla busca propiedades e instancias en las que se aceptan datos que no son de confianza para advertir a los desarrolladores de las posibles amenazas de divulgación de información o ataques por denegación de servicio (DoS). Esta regla se desencadena cuando:

En cada uno de estos casos, el resultado es el mismo: el contenido del sistema de archivos o de los recursos compartidos de red del equipo en el que se procesa el XML se expondrá al atacante, o el procesamiento de DTD puede usarse como un vector DoS.

Cómo corregir infracciones

  • Detecte y procese todas las excepciones XmlTextReader correctamente para evitar la divulgación de información de ruta de acceso.

  • Use XmlSecureResolver para restringir los recursos a los que puede obtener acceso XmlTextReader.

  • Establezca la propiedad XmlReader en XmlResolver null para evitar queabra ningún recurso externo.

  • Asegúrese de que la propiedad DataViewManager.DataViewSettingCollectionString se asigne desde un origen de confianza.

.NET Framework 3.5 y versiones anteriores

  • Deshabilite el procesamiento de DTD si trabaja con orígenes que no son de confianza; para ello, establezca la propiedad ProhibitDtd en true.

  • La clase XmlTextReader tiene una petición de herencia de plena confianza.

.NET Framework 4 y versiones posteriores

  • Evite habilitar DtdProcessing si trabaja con orígenes que no son de confianza; para ello, establezca la propiedad XmlReaderSettings.DtdProcessing en Prohibir u Omitir.

  • Asegúrese de que el método Load() tome una instancia XmlReader en todos los casos InnerXml.

Nota

Esta regla podría notificar falsos positivos en algunas instancias XmlSecureResolver válidas.

Cuándo suprimir las advertencias

A menos que esté seguro de que la entrada es de un origen de confianza, no suprima ninguna regla de esta advertencia.

Supresión de una advertencia

Si solo quiere suprimir una única infracción, agregue directivas de preprocesador al archivo de origen para deshabilitar y volver a habilitar la regla.

#pragma warning disable CA3075
// The code that's violating the rule is on this line.
#pragma warning restore CA3075

Para deshabilitar la regla de un archivo, una carpeta o un proyecto, establezca su gravedad en none del archivo de configuración.

[*.{cs,vb}]
dotnet_diagnostic.CA3075.severity = none

Para obtener más información, consulte Procedimiento para suprimir advertencias de análisis de código.

Ejemplos de pseudocódigo

Infracción 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;
        }
    }
}

Solución 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;
        }
    }
}

Infracción 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
        }
    }
}

Solución 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);
        }
    }
}

Infracción 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
        }
    }
}

Solución 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);
}

Infracción 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
        }
    }
}

Solución 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 );
        }
    }
}

Infracción 5

using System.Xml;
using System.Xml.XPath;

namespace TestNamespace
{
    public class UseXmlReaderForXPathDocument
    {
        public void TestMethod(string path)
        {
            XPathDocument doc = new XPathDocument(path); // warn
        }
    }
}

Solución 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);
        }
    }
}

Infracción 6

using System.Xml;

namespace TestNamespace
{
    class TestClass
    {
        public XmlDocument doc = new XmlDocument() { XmlResolver = new XmlUrlResolver() };
    }
}

Solución 6

using System.Xml;

namespace TestNamespace
{
    class TestClass
    {
        public XmlDocument doc = new XmlDocument() { XmlResolver = null }; // or set to a XmlSecureResolver instance
    }
}

Infracción 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 {}
        }
    }
}

Solución 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);
        }
    }
}

Nota

Aunque XmlReader.Create es el método recomendado para crear una instancia de XmlReader, existen diferencias de comportamiento con respecto a XmlTextReader. Un XmlReader de Create normaliza \r\n a \n en valores XML, mientras que XmlTextReader conserva la secuencia \r\n.