c# - leer - xmlreader java
DTD prohibido en la excepción de documento xml (3)
Recibo este error al intentar analizar a través de un documento XML en una aplicación de C #:
"Por razones de seguridad, la DTD está prohibida en este documento XML. Para habilitar el procesamiento de la DTD, establezca la propiedad ProhibitDtd en XmlReaderSettings en false y pase la configuración al método XmlReader.Create".
Para referencia, la excepción ocurrió en la segunda línea del siguiente código:
using (XmlReader reader = XmlReader.Create(uri))
{
reader.MoveToContent(); //here
while (reader.Read()) //(code to parse xml doc follows).
Mi conocimiento de Xml es bastante limitado y no tengo ni idea de qué es el procesamiento de DTD ni cómo hacer lo que sugiere el mensaje de error. ¿Alguna ayuda en cuanto a qué puede estar causando esto y cómo solucionarlo? Gracias...
En cuanto a arreglar esto, con un poco de mirar alrededor, descubrí que era tan simple como agregar:
XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
y pasar estas configuraciones en el método de creación.
[ACTUALIZACIÓN 3/9/2017]
Como algunos han señalado, .ProhibitDTDT ahora está en desuso. La respuesta del , a continuación, muestra la solución de reemplazo.
En primer lugar, algunos antecedentes.
¿Qué es una DTD?
El documento que está intentando analizar contiene una declaración de tipo de documento; Si observa el documento, encontrará cerca del principio una secuencia de caracteres que comienzan con <!DOCTYPE
y terminan con el correspondiente >
. Dicha declaración le permite a un procesador XML validar el documento contra un conjunto de declaraciones que especifican un conjunto de elementos y atributos y restringen qué valores o contenidos pueden tener.
Dado que las entidades también se declaran en DTD, una DTD permite a un procesador saber cómo expandir las referencias a las entidades. (La entidad pubdate
se puede definir para que contenga la fecha de publicación de un documento, como "15 de diciembre de 2012", y se &pubdate;
varias veces en el documento como &pubdate;
dado que la fecha real se da solo una vez, en la declaración de la entidad, este uso hace que sea más fácil mantener las distintas referencias a la fecha de publicación en el documento de manera coherente entre sí.)
¿Qué significa una DTD?
La declaración de tipo de documento tiene un significado puramente declarativo: un esquema para este tipo de documento, en la sintaxis definida en la especificación XML, se puede encontrar en tal y tal ubicación.
Algún software escrito por personas con una comprensión débil de los fundamentos de XML sufre de una confusión elemental sobre el significado de la declaración; asume que el significado de la declaración de tipo de documento no es declarativo (un esquema está por allí) sino imperativo (por favor valide este documento). El analizador que está utilizando parece ser un analizador de este tipo; asume que al entregarle un documento XML que tiene una declaración de tipo de documento, usted ha solicitado un cierto tipo de procesamiento. Sus autores podrían beneficiarse de un curso de recuperación sobre cómo aceptar los parámetros de tiempo de ejecución del usuario. (Usted ve lo difícil que es para algunas personas entender la semántica declarativa: incluso los creadores de algunos analizadores XML a veces no los entienden y se deslizan hacia el pensamiento imperativo en su lugar. Suspiro).
¿De qué ''razones'' de seguridad están hablando?
Algunas personas preocupadas por la seguridad han decidido que el procesamiento de DTD (validación o expansión de la entidad sin validación) constituye un riesgo de seguridad. Usando la expansión de entidades, es fácil hacer un flujo de datos XML muy pequeño que se expande, cuando todas las entidades están completamente expandidas, en un documento muy grande. Busca información sobre lo que se llama el "ataque de las mil millones de risas" si quieres leer más.
Una forma obvia de protegerse contra el ataque de las mil millones de risas es que aquellos que invocan un analizador en datos suministrados por el usuario o que no son de confianza invocan el analizador en un entorno que limita la cantidad de memoria o el tiempo en que se permite el consumo del proceso de análisis. Tales límites de recursos han sido partes estándar de los sistemas operativos desde mediados de los años sesenta. Sin embargo, por razones que me siguen ocultando, algunas personas preocupadas por la seguridad creen que la respuesta correcta es ejecutar analizadores con información no confiable sin límites de recursos , en la creencia aparente de que esto es seguro siempre y cuando sea imposible validar la información. contra un esquema acordado.
Por esta razón, su sistema le está diciendo que sus datos tienen un problema de seguridad.
Para algunas personas, la idea de que las DTD son un riesgo para la seguridad suena más a paranoia que a sentido común, pero no creo que sean correctas. Recuerde (a) que una paranoia saludable es lo que los expertos en seguridad necesitan en la vida, y (b) que cualquier persona realmente interesada en la seguridad insistiría en los límites de recursos en cualquier caso, en presencia de límites de recursos en el proceso de análisis, los DTD son inofensivo. La prohibición de las DTD no es paranoia sino fetichismo.
Ahora, con ese fondo fuera del camino ...
¿Cómo solucionas el problema?
La mejor solución es quejarse amargamente a su proveedor de que han sido engañados por una vieja historia de seguridad XML, y decirles que si les importa la seguridad deben hacer un análisis de seguridad racional en lugar de prohibir las DTD.
Mientras tanto, como sugiere el mensaje, puede "establecer la propiedad ProhibitDtd en XmlReaderSettings en falso y pasar la configuración al método XmlReader.Create". Si, de hecho, la entrada no es de confianza, también puede buscar formas de otorgar al proceso límites de recursos adecuados.
Y como alternativa (no lo recomiendo) puede comentar la declaración de tipo de documento en su entrada.
Tenga en cuenta que settings.ProhibitDtd ahora está obsoleto, use DtdProcessing en su lugar: (nuevas opciones de Ignorar, Parse o Prohibir)
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
y como se indica en este post: ¿Cómo funciona el ataque de DoS XML de las miles de millones de risas?
debe agregar un límite a la cantidad de caracteres para evitar ataques DoS:
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.MaxCharactersFromEntities = 1024;