CA3075 : Traitement DTD non sécurisé

Propriété Value
Identificateur de la règle CA3075
Titre Traitement DTD non sécurisé
Catégorie Sécurité
Le correctif est cassant ou non cassant Sans rupture
Activé par défaut dans .NET 8 Non

Cause

Si vous utilisez des instances de DtdProcessing non sécurisées ou référencez des sources d’entités externes, l’analyseur peut accepter une entrée non fiable et divulguer des informations sensibles à des personnes malveillantes.

Description de la règle

Une définition de type de document (DTD) est l’une des deux façons pour un analyseur XML de déterminer la validité d’un document, comme défini par la recommandation du World Wide Web Consortium (W3C) sur le langage XML (Extensible Markup Language) 1,0. Cette règle recherche les propriétés et instances où les données non fiables sont acceptées pour informer les développeurs de menaces de Information Disclosure éventuelles, ou des attaques par déni de service. Cette règle se déclenche quand :

Dans chacun de ces cas, le résultat est le même : le contenu du système de fichiers ou des partages réseau de l’ordinateur où le code XML est traité sera exposé à la personne malveillante, ou le traitement DTD peut être utilisé comme un vecteur d’attaque par déni de service.

Comment corriger les violations

  • Interceptez et traitez toutes les exceptions XmlTextReader  correctement pour éviter la divulgation d’informations relatives au chemin.

  • Utilisez XmlSecureResolver pour limiter les ressources auxquelles XmlTextReader peut accéder.

  • Empêchez XmlReader d’ouvrir des ressources externes en affectant à la propriété XmlResolver la valeur null.

  • Vérifiez que la propriété DataViewManager.DataViewSettingCollectionString est affectée depuis une source fiable.

.NET Framework 3.5 et versions antérieures

  • Désactivez le traitement DTD si vous utilisez des sources non fiables en affectant à la propriété ProhibitDtd la valeur true.

  • La classe XmlTextReader a une demande d’héritage de confiance totale.

.NET Framework 4 et versions ultérieures

  • Évitez d’activer DtdProcessing si vous utilisez des sources non fiables en affectant à la propriété XmlReaderSettings.DtdProcessing la valeur Prohibit ou Ignore.

  • Vérifiez que la méthode Load() accepte une instance de XmlReader dans tous les cas InnerXml.

Notes

Cette règle peut signaler des faux positifs sur certaines instances de XmlSecureResolver valides.

Quand supprimer les avertissements

Sauf si vous êtes sûr que l’entrée provient d’une source fiable, ne supprimez aucune règle de cet avertissement.

Supprimer un avertissement

Si vous voulez supprimer une seule violation, ajoutez des directives de préprocesseur à votre fichier source pour désactiver et réactiver la règle.

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

Pour désactiver la règle sur un fichier, un dossier ou un projet, définissez sa gravité sur none dans le fichier de configuration.

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

Pour plus d’informations, consultez Comment supprimer les avertissements de l’analyse de code.

Exemples de pseudo-code

Violation 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;
        }
    }
}

Solution 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;
        }
    }
}

Violation 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
        }
    }
}

Solution 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);
        }
    }
}

Violation 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
        }
    }
}

Solution 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);
}

Violation 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
        }
    }
}

Solution 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 );
        }
    }
}

Violation 5

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

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

Solution 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);
        }
    }
}

Violation 6

using System.Xml;

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

Solution 6

using System.Xml;

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

Violation 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 {}
        }
    }
}

Solution 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);
        }
    }
}

Notes

Bien que XmlReader.Create soit la méthode recommandée pour créer une instance de XmlReader, il existe des différences de comportement par rapport à XmlTextReader. XmlReader de Create normalise \r\n en \n dans les valeurs XML, tandis que XmlTextReader conserve la séquence de \r\n.