web-dev-qa-db-fra.com

DTD interdite dans l'exception de document xml

J'obtiens cette erreur lorsque j'essaie d'analyser un document XML dans une application C #:

"Pour des raisons de sécurité, la DTD est interdite dans ce document XML. Pour activer le traitement DTD, définissez la propriété ProhibitDtd sur XmlReaderSettings sur false et transmettez les paramètres à la méthode XmlReader.Create."

Pour référence, l'exception s'est produite à la deuxième ligne du code suivant:

using (XmlReader reader = XmlReader.Create(uri))
{
    reader.MoveToContent(); //here

    while (reader.Read()) //(code to parse xml doc follows).

Ma connaissance de Xml est assez limitée et je n'ai aucune idée de ce qu'est le traitement DTD ni comment faire ce que le message d'erreur suggère. Une aide quant à ce qui peut être à l'origine de cela et comment y remédier? Merci...

41
ConnorU

Notez que settings.ProhibitDtd est désormais obsolète, utilisez plutôt DtdProcessing: (nouvelles options Ignorer, Analyser ou Interdire)

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;

et comme indiqué dans cet article: Comment fonctionne l'attaque du milliard de rires XML DoS?

vous devez ajouter une limite au nombre de caractères pour éviter les attaques DoS:

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.MaxCharactersFromEntities = 1024;
31
Dr. Aaron Dishno

Tout d'abord, quelques informations.

Qu'est-ce qu'une DTD?

Le document que vous essayez d'analyser contient une déclaration de type de document; si vous regardez le document, vous trouverez vers le début une séquence de caractères commençant par <!DOCTYPE et se terminant par le >. Une telle déclaration permet à un processeur XML de valider le document par rapport à un ensemble de déclarations qui spécifient un ensemble d'éléments et d'attributs et contraignent les valeurs ou le contenu qu'ils peuvent avoir.

Étant donné que les entités sont également déclarées dans les DTD, une DTD permet à un processeur de savoir comment étendre les références aux entités. (L'entité pubdate peut être définie pour contenir la date de publication d'un document, comme "15 décembre 2012", et désignée plusieurs fois dans le document par &pubdate; - puisque la date réelle n'est donnée qu'une seule fois, dans la déclaration d'entité, cette utilisation facilite la cohérence entre les différentes références à la date de publication dans le document.)

Que signifie une DTD?

La déclaration de type de document a une signification purement déclarative: un schéma pour ce type de document, dans la syntaxe définie dans la spécification XML, peut être trouvé à tel ou tel emplacement.

Certains logiciels écrits par des personnes ayant une faible compréhension des principes fondamentaux de XML souffrent d'une confusion élémentaire quant au sens de la déclaration; il suppose que la signification de la déclaration de type de document n'est pas déclarative (un schéma est là-bas) mais impératif (veuillez valider ce document). L'analyseur que vous utilisez semble être un tel analyseur; il suppose qu'en lui remettant un document XML qui a une déclaration de type de document, vous avez demandé un certain type de traitement. Ses auteurs pourraient bénéficier d'un cours de rattrapage sur la façon d'accepter les paramètres d'exécution de l'utilisateur. (Vous voyez à quel point il est difficile pour certaines personnes de comprendre la sémantique déclarative: même les créateurs de certains analyseurs XML ne parviennent parfois pas à les comprendre et à glisser à la place dans la pensée impérative. Soupir.)

De quelles "raisons de sécurité" parlent-ils?

Certaines personnes soucieuses de la sécurité ont décidé que le traitement DTD (validation ou extension d'entité sans validation) constitue un risque pour la sécurité. En utilisant l'extension d'entité, il est facile de créer un très petit flux de données XML qui se développe, lorsque toutes les entités sont entièrement développées, en un très grand document. Recherchez des informations sur ce qu'on appelle "l'attaque du milliard de rires" si vous voulez en savoir plus.

Une façon évidente de se protéger contre l'attaque du milliard de rires est pour ceux qui invoquent un analyseur sur des données fournies par l'utilisateur ou non fiables d'appeler l'analyseur dans un environnement qui limite la quantité de mémoire ou le temps que le processus d'analyse est autorisé à consommer. Ces limites de ressources font partie intégrante des systèmes d'exploitation depuis le milieu des années 60. Pour des raisons qui restent obscures pour moi, cependant, certaines personnes soucieuses de la sécurité croient que la bonne réponse consiste à exécuter des analyseurs syntaxiques sur des entrées non fiables sans limites de ressources, dans la croyance apparente que cela est sûr tant que vous rendre impossible la validation de l'entrée par rapport à un schéma convenu.

C'est pourquoi votre système vous indique que vos données ont un problème de sécurité.

Pour certaines personnes, l'idée que les DTD constituent un risque pour la sécurité ressemble plus à de la paranoïa qu'à du bon sens, mais je ne pense pas qu'elles soient correctes. Rappelez-vous (a) qu'une paranoïa saine est ce dont les experts en sécurité ont besoin dans la vie, et (b) que toute personne vraiment intéressée par la sécurité insistera sur les limites de ressources dans tous les cas - en présence de limites de ressources sur le processus d'analyse, les DTD sont inoffensif. L'interdiction des DTD n'est pas de la paranoïa mais du fétichisme.


Maintenant, avec ce contexte à l'écart ...

Comment résolvez-vous le problème?

La meilleure solution est de se plaindre amèrement à votre fournisseur d'avoir été aspiré par le récit d'une vieille femme sur la sécurité XML, et de lui dire que s'ils se soucient de la sécurité, ils devraient faire une analyse de sécurité rationnelle au lieu d'interdire les DTD.

Pendant ce temps, comme le message le suggère, vous pouvez "définir la propriété ProhibitDtd sur XmlReaderSettings sur false et transmettre les paramètres dans la méthode XmlReader.Create". Si l'entrée n'est en fait pas approuvée, vous pouvez également rechercher des moyens de donner au processus des limites de ressources appropriées.

Et comme solution de rechange (je ne le recommande pas), vous pouvez commenter la déclaration de type de document dans votre entrée.

66

En ce qui concerne la correction de cela, avec un peu de recherche, j'ai trouvé que c'était aussi simple que d'ajouter:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;

et en passant ces paramètres dans la méthode create.

[MISE À JOUR 3/9/2017]

Comme certains l'ont souligné, .ProhibitDTDT est désormais obsolète. Dr. Aaron Dishno la réponse ci-dessous montre la solution de remplacement

29
ConnorU