¿Cómo puedo usar las diversas bibliotecas XML de PHP para obtener una funcionalidad similar a la de DOM y evitar las vulnerabilidades DoS, como Billion Laughs o Quadratic Blowup?

Estoy escribiendo una aplicación web que tiene una API XML en PHP, y me preocupan tres vulnerabilidades específicas, todas relacionadas con las definiciones DOCTYPE en línea: inclusión de archivos locales, explosión de entidades cuadráticas y explosión de entidades exponenciales. Me encantaría usar las bibliotecas integradas de PHP (5.3), pero quiero asegurarme de que no soy susceptible a estas.

Descubrí que puedo eliminar LFI con libxml_disable_entity_loader, pero esto no ayuda con las declaraciones ENTITY en línea, incluidas las entidades que hacen referencia a otras entidades.

La biblioteca SimpleXML (SimpleXMLElement, simplexml_load_string, etc.) es excelente porque es un analizador de DOM y todas mis entradas son bastante pequeñas; me permite usar xpath y manipular el DOM con bastante facilidad. No puedo imaginar cómo detener las declaraciones de ENTIDAD. (Me encantaría deshabilitar todas las definiciones de DOCTYPE en línea, si es posible).

La biblioteca del analizador XML (xml_parser_create, xml_set_element_handler, etc.) me permite configurar el controlador predeterminado, que incluye entidades, con xml_set_default_handler. Puedo piratearlo para entidades no reconocidas, simplemente devuelve la cadena original (es decir, "& ent;"). Sin embargo, esta biblioteca es frustrante: debido a que es un analizador SAX, tengo que escribir un montón de manejadores (hasta 9 ...).

Entonces, ¿es posible usar las bibliotecas integradas, sacar objetos similares a DOM y protegerme de estas diversas vulnerabilidades DoS? Gracias

Esta página describe las tres vulnerabilidades y proporciona una solución ... si solo estuviera utilizando .NET:http://msdn.microsoft.com/en-us/magazine/ee335713.aspx

ACTUALIZAR:

<code><?php
$s = <<<EOF
<?xml version="1.0?>
<!DOCTYPE data [
<!ENTITY en "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa....">
]>
<data>&en;&en;&en;&en;&en;&en;&en;&en;&en;&en;&en;&en;.....</data>
EOF;
$doc = new DOMDocument();
$doc->loadXML($s);
var_dump($d->lastChild->nodeValue);
?>
</code>

Lo intentéloadXML($s, LIBXML_NOENT); también. En ambos casos termino tirando 300+ MB. ¿Hay algo que todavía me falta?

Respuestas a la pregunta(2)

Su respuesta a la pregunta