Como posso usar várias bibliotecas XML do PHP para obter funcionalidade semelhante a DOM e evitar vulnerabilidades do DoS, como o Billion Laughs ou o Quadratic Blowup?

Estou escrevendo um aplicativo da web que tem uma API XML em PHP e estou preocupado com três vulnerabilidades específicas, todas relacionadas a definições DOCTYPE em linha: inclusão de arquivo local, blowup de entidade quadrática e blowup de entidade exponencial. Eu adoraria usar as bibliotecas internas do PHP (5.3), mas quero ter certeza de que não sou suscetível a elas.

Descobri que posso eliminar LFI com libxml_disable_entity_loader, mas isso não ajuda com declarações ENTITY embutidas, incluindo entidades que se referem a outras entidades.

A biblioteca SimpleXML (SimpleXMLElement, simplexml_load_string, etc) é ótima porque é um analisador DOM e todas as minhas entradas são bem pequenas; Isso me permite usar o xpath e manipular o DOM facilmente. Não consigo descobrir como parar as declarações do ENTITY. (Eu ficaria feliz em desabilitar todas as definições do DOCTYPE, se possível).

A biblioteca XML Parser (xml_parser_create, xml_set_element_handler, etc) me permite definir o manipulador padrão, que inclui entidades, com xml_set_default_handler. Eu posso cortar isso para entidades não reconhecidas, ele simplesmente retorna a string original (isto é, "& ent;"). Esta biblioteca é frustrante: porque é um analisador SAX, eu tenho que escrever um monte de manipuladores (até 9).

Então, é possível usar as bibliotecas embutidas, obter objetos do tipo DOM e proteger-me dessas diversas vulnerabilidades do DoS? obrigado

Esta página descreve as três vulnerabilidades e fornece uma solução ... se eu estivesse usando o .NET:http://msdn.microsoft.com/pt-br/magazine/ee335713.aspx

ATUALIZAR:

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

eu tenteiloadXML($s, LIBXML_NOENT); também. Em ambos os casos acabo despejando mais de 300 MB. Há algo que ainda estou sentindo falta?

questionAnswers(2)

yourAnswerToTheQuestion