Pular para o conteúdo
Todos os conceitos

Fechando o XXE

A defesa completa recusa o DTD; sem DTD não há onde declarar entidade, e todas as variantes somem.

Todas as variantes do XXE (ler arquivo, SSRF, vazamento fora de banda, billion laughs) dependem de uma coisa: o parser aceitar o DTD e processar o que ele declara. Então a defesa mais forte é a mais simples: recusar o DTD por inteiro. Sem <!DOCTYPE>, não há onde declarar entidade, e as quatro variantes fecham de uma vez.

Desligar só a expansão de entidades gerais não basta: o DTD continua sendo processado, as entidades de parâmetro ainda rodam (vazamento fora de banda) e o billion laughs ainda cresce. Por isso o botão que importa é o do DTD.

O ajuste tem o mesmo espírito em cada biblioteca:

  • Java: factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true).
  • Python: use o pacote defusedxml no lugar da biblioteca padrão.
  • libxml2 (e lxml): não ligue as opções NOENT nem DTDLOAD.
  • .NET: DtdProcessing = DtdProcessing.Prohibit.

Em todas, a ideia é a mesma: não aceitar DTD. Se o seu formato realmente precisa de um, pelo menos nunca resolva entidades externas e limite a expansão.

XML que chega <!DOCTYPE invoice [ <!ENTITY x SYSTEM... <invoice>... parser com DTD recusado disallow-doctype DOCTYPE rejeitado nenhuma entidade é declarada nem resolvida
Com o DTD recusado no parser, o <!DOCTYPE> do pedido é rejeitado e nenhuma entidade chega a ser declarada ou resolvida.

Aparece nestes desafios