DTD interdite dans le document xml exception

j'obtiens cette erreur en essayant 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 à false et passez les paramètres dans XmlReader.Méthode de création."

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 du Xml est assez limitée et je n'ai aucune idée de ce qu'est le traitement DTD ni de la façon de faire ce que le message d'erreur suggère. Toute aide à ce qui peut être à l'origine de ce et comment le résoudre? grâce...

38
demandé sur ConnorU 2012-12-13 10:16:18

3 réponses

notez que les paramètres.ProhibitDtd est maintenant obsolète, utilisez DtdProcessing à la place: (nouvelles options D'ignorer, Parse, ou interdire)

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

et comme indiqué dans ce post: comment le milliard de rires DoS attaque travailler?

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;
24
répondu Dr. Aaron Dishno 2017-05-23 12:02:39

D'abord, un peu de fond.

Qu'est-ce qu'une DTD?

le document que vous tentez d'analyser contient une déclaration de type de document; si vous regardez le document, vous trouverez près du début une séquence de caractères commençant par <!DOCTYPE et se terminant par le > correspondant . Cette déclaration permet à un processeur XML pour valider le document par rapport à un ensemble de déclarations qui spécifient un ensemble d'éléments et d'attributs et limiter les valeurs ou les contenus qu'ils peuvent avoir.

puisque 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 pourrait être définie pour contenir la date de publication d'un document, comme" 15 décembre 2012", et mentionnée à plusieurs reprises dans le document comme &pubdate; -- puisque la date réelle n'est donnée qu'une seule fois, dans la déclaration d'entité, cet usage rend plus facile de garder les différents les références à la date de publication dans le document sont cohérentes.)

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 endroit.

Certains logiciels écrits par des personnes ayant une faible compréhension des fondamentaux XML souffre d'une confusion élémentaire sur le 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érative (veuillez valider ce document). L'analyseur que vous utilisez semble être un tel analyseur; il suppose qu'en lui remettant un document XML qui comporte 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 manière d'accepter les paramètres d'exécution la part de l'utilisateur. (Vous voyez combien 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 se glissent dans la pensée impérative à la place. Soupir.)

quelles sont ces "raisons de sécurité" dont ils parlent?

certaines personnes soucieuses de la sécurité ont décidé que le traitement DTD (validation, ou expansion de l'entité sans validation) constitue un risque pour la sécurité. Utiliser l'expansion de l'entité, il est facile de faire un très petit flux de données XML qui s'étend, lorsque toutes les entités sont entièrement étendues, dans un très grand document. Cherchez des informations sur ce qu'on appelle "l'attaque du milliard de rires" si vous voulez en savoir plus.

un moyen évident 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 de confiance pour invoquer l'analyseur dans un environnement qui limite la quantité de mémoire ou de temps 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 1960. Pour des raisons qui restent obscures pour moi, cependant, certaines personnes soucieuses de la sécurité croient que la bonne réponse est d'exécuter des analyseurs sur des entrées non fiables sans limites de ressources , dans la croyance apparente que c'est sûr aussi longtemps que vous faites impossible de valider l'entrée en fonction d'un schéma convenu.

c'est pourquoi votre système vous dit que votre données a un problème de sécurité.

pour certaines personnes, l'idée que les DTDs sont un risque de sécurité ressemble plus à de la paranoïa qu'à du bon sens, mais je ne crois pas qu'ils soient corrects. 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é insisterait sur les limites de ressources dans tous les cas -- en présence de limites de ressources sur le processus d'analyse, les DTDs sont inoffensifs. L'interdiction des DTDs n'est pas de la paranoïa mais du fétichisme.


maintenant, avec ce fond hors du chemin ...

comment résoudre le problème?

la meilleure solution est de se plaindre amèrement à votre vendeur qu'ils ont été dupés par une vieille histoire de wive sur la sécurité XML, et de leur dire que s'ils se soucient de la sécurité, ils devraient faire une analyse de sécurité rationnelle au lieu d'interdire les DTDs.

pendant ce temps, comme le suggère le message, vous peut " définir la propriété ProhibitDtd sur XmlReaderSettings à false et passer les paramètres dans XmlReader.Méthode de création."Si les données ne sont pas fiables, vous pourriez aussi chercher des moyens de limiter les ressources du processus.

et comme solution de rechange (Je ne recommande pas cela) vous pouvez commenter la déclaration de type de document dans votre entrée.

57
répondu C. M. Sperberg-McQueen 2012-12-13 20:53:05

pour ce qui est de réparer ceci, en regardant autour de moi, j'ai trouvé que c'était aussi simple que d'ajouter:

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

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

[UPDATE 3/9/2017]

comme certains l'ont souligné, .Prohibitddt est maintenant déprécié. Dr. Aaron Dishno 'S réponse, ci-dessous, montre la solution de remplacement

29
répondu ConnorU 2017-05-23 12:02:39