Compartir a través de


Seguridad de LINQ to XML

Actualización: November 2007

Este tema describe los problemas de seguridad asociados a LINQ to XML. Además, proporciona algunas indicaciones para reducir la exposición a esos problemas de seguridad.

Información general de seguridad de LINQ to XML

LINQ to XML se ha diseñado más para la comodidad de programación que para aplicaciones de servidor con estrictos requisitos de seguridad. La mayoría de escenarios XML consisten en el procesamiento de documentos XML de confianza en lugar del procesamiento de documentos XML que no son de confianza que se suben a un servidor. LINQ to XML está optimizado para esos escenarios.

Si debe procesar datos que no son de confianza de orígenes desconocidos, Microsoft recomienda usar una instancia de la clase XmlReader que se ha configurado para filtrar ataques de denegación de servicio (DoS) XML.

Si ha configurado XmlReader para mitigar los ataques de denegación de servicio, puede usar ese lector para rellenar un árbol de LINQ to XML y seguir sacando provecho de las mejoras de productividad del programador de LINQ to XML. Muchas técnicas de reducción de riesgo implican crear lectores configurados para mitigar el problema de seguridad y crear a continuación instancias de un árbol XML mediante el lector configurado.

XML es intrínsecamente vulnerable a ataques de denegación de servicio porque los documentos no tienen límite en el tamaño, la profundidad, el tamaño de nombre de elemento, etc. Independientemente del componente que use para procesar XML, siempre debería estar preparado para reciclar el dominio de la aplicación si utiliza demasiados recursos.

Reducción del riesgo de ataques de XML, XSD, XPath y XSLT

LINQ to XML se basa en XmlReader y XmlWriter. LINQ to XML admite XSD y XPath mediante métodos de extensión en los espacios de nombres System.Xml.Schema y System.Xml.XPath. El uso de las clases XmlReader, XPathNavigator y XmlWriter combinado con LINQ to XML, puede invocar XSLT para transformar árboles XML.

Cuando trabaja en un entorno menos seguro, existen varios problemas de seguridad asociados con XML y con el uso de clases en System.Xml, System.Xml.Schema, System.Xml.XPath y System.Xml.Xsl. Algunos de los problemas son:

  • XSD, XPath y XSLT son lenguajes basados en cadenas en los que puede especificar operaciones que consumen mucho tiempo o memoria. Es responsabilidad de los programadores que toman cadenas XSD, XPath o XSLT de orígenes que no son de confianza validar que dichas cadenas no son malintencionadas o supervisar y reducir la posibilidad de que la evaluación de esas cadenas provoque un consumo excesivo de recursos del sistema.

  • Los esquemas XSD (incluyendo los esquemas en línea) son intrínsecamente vulnerables a ataques de denegación de servicio. No se deben aceptar esquemas de orígenes que no sean de confianza.

  • XSD y XSLT pueden incluir referencias a otros archivos y esas referencias pueden producir ataques entre dominios y zonas.

  • Las entidades externas de DTD pueden tener como resultado ataques entre dominios y zonas.

  • Las DTD son vulnerables a ataques de denegación de servicio.

  • Los documentos XML con una profundidad excepcional pueden plantear problemas de denegación de servicio. Es posible que desee limitar la profundidad de documentos XML.

  • No se admiten componentes como, por ejemplo, objetos NameTable, XmlNamespaceManager y XmlResolver, de ensamblados que no sean de confianza.

  • Lectura de datos en fragmentos para mitigar ataques de documentos de gran tamaño.

  • Los bloques de scripts de las hojas de estilo XSLT pueden dar lugar a varios ataques.

  • Validar cuidadosamente antes de crear expresiones XPath dinámicas.

Para obtener más información acerca de esos ataques y su mitigación, vea Seguridad y aplicaciones System.Xml.

Problemas de seguridad de LINQ to XML

Los problemas de seguridad de este tema no se presentan en ningún orden específico. Todos los problemas son importantes y deben solucionarse de forma adecuada.

Un ataque de elevación de privilegios que tiene éxito proporciona a un ensamblado malintencionado más control sobre su entorno. Un ataque de elevación de privilegios que tiene éxito puede tener como resultado una revelación de datos, una denegación de servicio, etc.

Las aplicaciones no deben revelar datos a los usuarios que no están autorizados a verlos.

Los ataques de denegación de servicio hacen que el analizador XML o LINQ to XML consuman excesiva memoria o tiempo de CPU. Los ataques de denegación de servicio se consideran menos graves que los ataques de elevación de privilegios o los ataques de revelación de datos. No obstante, son importantes en un escenario en el que un servidor debe procesar documentos XML de orígenes que no sean de confianza.

Las excepciones y los mensajes de error pueden revelar datos

La descripción de un error puede revelar datos como la transformación de datos, los nombres de archivos o los detalles de implementación. Los mensajes de error no se deben mostrar a los autores de la llamada que no son de confianza. Debe detectar todos los errores e notificarlos con sus propios mensajes de error.

No llamar a CodeAccessPermissions.Assert en un controlador de eventos

Un ensamblado puede tener más o menos permisos. Un ensamblado con más permisos cuenta con un mayor control sobre el equipo y sus entornos.

Si el código de un ensamblado con más permisos llama a CodeAccessPermission.Assert en un controlador de eventos y, a continuación, el árbol XML se pasa a un ensamblado malintencionado que tiene permisos restringidos, el ensamblado malintencionado puede hacer que se genere un evento. Como el evento ejecuta código que está en el ensamblado con más permisos, el ensamblado malintencionado funcionará con privilegios elevados.

Microsoft recomienda no llamar nunca a CodeAccessPermission.Assert en un controlador de eventos.

Las DTD no son seguras

Las entidades de DTD son inseguras intrínsecamente. Un documento XML malintencionado que contiene DTD puede hacer que el analizador use toda la memoria y todo el tiempo de CPU, lo que provocaría un ataque de denegación de servicio. Por lo tanto, en LINQ to XML, el procesamiento de DTD está desactivado de forma predeterminada. No debe aceptar DTD de orígenes que no sean de confianza.

Un ejemplo de DTD aceptadas de orígenes que no son de confianza es una aplicación web que permite a los usuarios cargar un archivo XML que hace referencia a una DTD y un archivo de DTD. Al validar el archivo, una DTD malintencionada puede ejecutar un ataque de denegación de servicio en el servidor. Otro ejemplo de DTD aceptadas de orígenes que no son de confianza es hacer referencia a una DTD en un recurso compartido de red que también permite el acceso FTP anónimo.

Evitar la asignación excesiva de búfer

Los desarrolladores de aplicaciones deben tener en cuenta que orígenes de datos extremadamente grandes pueden provocar un agotamiento de los recursos y ataques de denegación de servicio.

Si un usuario malintencionado envía o carga un documento XML de gran tamaño, puede hacer que LINQ to XML consuma demasiados recursos del sistema. Esto puede representar un ataque de denegación de servicio. Para evitarlo, puede ajustar la propiedad XmlReaderSettings.MaxCharactersInDocument y crear un lector con un límite en el tamaño del documento que puede cargar. El lector se usa a continuación para crear el árbol XML.

Por ejemplo, si sabe que el tamaño máximo previsto de los documentos XML que provienen de un origen que no es de confianza va a ser inferior a 50 KB, establezca XmlReaderSettings.MaxCharactersInDocument en 100.000. Esto no será un inconveniente para el procesamiento de sus documentos XML y a la vez contrarrestará amenazas de denegación de servicio en las que se podrían cargar documentos que consumirían grandes cantidades de memoria.

Evitar la expansión excesiva de entidades

Uno de los ataques de denegación de servicio conocidos cuando se usa una DTD es un documento que provoca una expansión excesiva de entidades. Para evitar que esto se produzca, puede establecer la propiedad XmlReaderSettings.MaxCharactersFromEntities y crear un lector que tenga un límite en el número de caracteres producidos por la expansión de la entidad. El lector se usa a continuación para crear el árbol XML.

Limitar la profundidad de la jerarquía XML

Un posible ataque de denegación de servicio consiste en enviar un documento que tiene una profundidad de jerarquía excesiva. Para evitarlo, puede encapsular XmlReader en su propia clase que cuenta la profundidad de los elementos. Si la profundidad supera un nivel razonable predeterminado, puede finalizar el procesamiento del documento malintencionado.

Protegerse frente a implementaciones de XmlReader o XmlWriter que no son de confianza

Los administradores deben comprobar que las implementaciones de XmlReader o XmlWriter proporcionadas de forma externa tienen nombres seguros y se han registrado en la configuración del equipo. Esto evita que se cargue un código malintencionado que simula ser un lector o escritor.

Liberar periódicamente objetos que hacen referencia a XName

Para protegerse frente a cierto tipo de ataques, los programadores de aplicaciones deben liberar todos los objetos que hacen referencia a un objeto XName en el dominio de la aplicación de forma periódica.

Protegerse frente a nombres XML aleatorios

Las aplicaciones que toman datos de orígenes que no son de confianza deben plantearse el uso de XmlReader, que se incluye en el código personalizado para inspeccionar la posibilidad de nombres y espacios de nombre XML aleatorios. Si se detectan nombres y espacios de nombres XML aleatorios, la aplicación puede finalizar el procesamiento del documento malintencionado.

Es posible que desee limitar los nombres incluidos en cualquier espacio de nombres dado (incluyendo nombres que no están en ningún espacio de nombres) a una cantidad razonable.

Los componentes de software que comparten un árbol de LINQ to XML pueden tener acceso a las anotaciones

LINQ to XML se puede usar para crear canalizaciones de procesamiento en las que diferentes componentes de la aplicación cargan, validan, consultan, transforman, actualizan y guardan datos XML que se pasan entre componentes como árboles XML. Esto puede ayudarle a optimizar el rendimiento, porque la sobrecarga de carga y serialización de objetos a texto XML se realiza únicamente en los extremos de la canalización. Sin embargo, los desarrolladores deben tener en cuenta que otros componentes puedes tener acceso a todas las anotaciones y controladores de eventos creados por un componente. Esto puede crear varias vulnerabilidades cuando los componentes tienen diferentes niveles de confianza. Para crear canalizaciones seguras en componentes con un nivel de confianza inferior, debe serializar los objetos LINQ to XML a texto XML antes de pasar los datos a un componente que no es de confianza.

Common Language Runtime (CLR) proporciona cierta seguridad. Por ejemplo, un componente que no incluye una clase privada no puede tener acceso a anotaciones con claves creadas por esa clase. No obstante, las anotaciones pueden ser eliminadas por componentes que no las leen. Esto se podría usar como ataque de manipulación.

Vea también

Conceptos

Guía de programación (LINQ to XML)

Otros recursos

Seguridad y aplicaciones System.Xml