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?