2017-03-13 5 views
2

Existe-t-il un moyen d'empêcher la classe XmlReader de .NET d'étendre les entités XML à leur valeur lors de la lecture du contenu?Empêche XmlReader d'étendre les entités XML

Par exemple, supposons que le code XML suivant est utilisé comme entrée:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE author PUBLIC "ISO 8879:1986//ENTITIES Added Latin 1//EN//XML" "http://www.oasis-open.org/docbook/xmlcharent/0.3/iso-lat1.ent" > 
<author>&aacute;</author> 

Supposons qu'il est impossible d'atteindre la DTD externe OASIS nécessaire pour l'expansion de l'entité aacute. Je voudrais que le lecteur lise, en séquence, l'élément author, puis le noeud aacute de type EntityReference, et enfin l'élément end de l'auteur, sans émettre d'erreur. Comment puis-je atteindre cet objectif?

MISE À JOUR: Je souhaite également empêcher l'expansion d'entités de caractères telles que &#x00E1;.

+0

Quelle .net version du framework? – galakt

+0

@galakt .NET 4.5 –

Répondre

1

Une façon de le faire est d'utiliser `XmlTextReader », comme ceci:

using (var reader = new XmlTextReader(@"your url")) 
{ 
    // note this 
    reader.EntityHandling = EntityHandling.ExpandCharEntities; 
    while (reader.Read()) 
    { 
     // here it will be EntityReference with no exceptions 
    } 
} 

Si ce n'est pas une option - vous pouvez faire la même chose avec XmlReader, mais une réflexion sera nécessaire (au moins I ne pas connaître d'une autre manière):

using (var reader = XmlReader.Create(@"your url", new XmlReaderSettings() { 
    DtdProcessing = DtdProcessing.Ignore // or Parse 
})) { 
    // get internal property which has the same function as above in XmlTextReader 
    reader.GetType().GetProperty("EntityHandling", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(reader, EntityHandling.ExpandCharEntities); 
    while (reader.Read()) { 
      // here it will be EntityReference with no exceptions 
    } 
} 
+0

Ceci est assez proche de ce que je recherche, mais je voudrais également empêcher l'expansion des entités char. Les valeurs de EntityHandling enum n'autorisent pas ce cas également. –

+0

@GabrielS Je comprends que vous ne voulez pas étendre les entités, mais pourquoi ne pas développer des entités char? – Evk

+0

L'application sur laquelle je travaille doit prendre le contrôle de l'expansion de toutes les entités XML, car elle effectue un traitement personnalisé pour chacune d'entre elles. C'est pourquoi il doit recevoir des références d'entité non expansées à partir de 'XmlReader' au lieu du résultat étendu. –

1

L'analyse XML est dangereuse. Dans certains cas, il permet aux attaques CVE et Denial-of-Service.

Par exemple CVE-2016-3255

il a été EXAMINÉS également sur Black Hat EU 2013

Le document le plus intéressé est MLDTDEntityAttacks qui fournit et Implémentations Recomendations pour les développeurs.

Récupérer des ressources:

<!DOCTYPE roottag [ 
<!ENTITY windowsfile SYSTEM "file:///c:/boot.ini"> 
]> 
<roottag> 
<sometag>&windowsfile;</sometag> 
</roottag> 

DoS:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<!DOCTYPE root 
    [ 
    <!ENTITY a0 "test" > 
    <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;"> 
    <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;"> 
    <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;"> 
    <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;"> 
    ]> 
<root>&a4;</root> 

Retour à votre question.
Comme @Evk a écrit: En réglant EntityHandling, vous pouvez empêcher l'expansion de toutes les entités sauf CharEntities.

Je ne connais pas de solution pour empêcher l'expansion de CharEntity à l'exception de votre propre implémentation XmlReader.

Je pense que vous voulez aussi éviter que l'analyse syntaxique &amp; &apos; &lt; &gt; &quot;

Pour votre information comment et où XmlTextReader parse CharEntity

XmlTextReader
ParseElementContent
& case
ParseText
Char entity case
Cette fonction analyse enfin la référence d'entité de caractère numérique (par ex. &#32; et &#x00E1;)
ParseNumericCharRefInline


Cette fonction parse appelée référence d'entité de caractères (&amp; &apos; &lt; &gt; &quot;)
ParseNamedCharRef

+0

Bien que vos liens vers les parties exactes des entités de gestion de code fournissent des informations utiles, réécrire le 'XmlTextReaderImpl' n'est pas vraiment une option pour moi. Je ne vois pas non plus la possibilité d'hériter et de remplacer cette partie spécifique de cette classe, d'autant plus que ce n'est même pas public. La seule option que je vois maintenant est de pré-traiter le XML pour changer les entités en un texte spécial qui n'est plus vu comme des références d'entité par 'XmlReader', mais que je peux ensuite traiter sans extension. –