Este artigo foi traduzido por máquina.

Informativos sobre segurança

Ataques de negação de serviço ao XML e defesas

Bryan Sullivan

Ataques de negação de serviço (DoS) estão entre os tipos de ataques contra Web sites mais antigos. Documentado DoS ataques existem pelo menos, longe verso como 1992, predates injeção de SQL (descoberta em 1998), scripts entre sites (JavaScript não foi inventado até 1995) e falsificação de solicitação intersite (CSRF ataques geralmente exigem cookies de sessão e cookies não foram introduzidos até 1994).

Desde o início, ataques eram altamente populares com a comunidade hacker e é fácil entender por que. Um invasor “ script kiddie ” único com um mínimo de habilidade e recursos poderia gerar uma inundação de solicitações TCP SYN (para sincronização) suficientes para bater um site do serviço. Mundo comércio iniciantes, isso foi devastador: Se os usuários não foi possível obter a um site, eles não puderam gastar muito bem dinheiro existe tanto. Ataques doS eram o equivalente virtual de erecting fios razor fence ao redor de um armazenamento de Tijolo e cimento, exceto que poderia ser atacado qualquer armazenamento em qualquer hora, dia ou da noite.

Nos anos, ataques SYN flood tem sido atenuadas amplamente por aprimoramentos no hardware de rede e software do servidor de Web. Entretanto, recentemente houve resurgence interesse em ataques dentro da comunidade de segurança — não para “ antigo escola ” nível de rede DoS, mas para o nível de aplicativo DoS e particularmente analisador XML DoS.

Ataques XML são extremamente assimétricas: para entregar a carga do ataque, um invasor precisa gastar apenas uma fração da energia de processamento ou largura de banda da vítima precisa gastar para manipular a carga. Pior ainda, DoS vulnerabilidades no código que processa XML também são extremamente difundidas. Mesmo se você estiver usando analisadores exaustivamente testados como aqueles encontrados nas classes System.XML do Microsoft.NET Framework, seu código pode ainda estar vulnerável a menos que você execute etapas explícitas para protegê-lo.

Este artigo descreve algumas os novos XML ataques. Ele também mostra maneiras para você detectar vulnerabilidades potenciais de negação e como atenuá-los em seu código.

XML Bombs

Um tipo de ataque de XML especialmente desagradável é bomba XML — um bloco XML que é bem formado e válido de acordo com as regras de um esquema XML, mas que falha ou trava um programa quando esse programa tentar analisá-lo. O exemplo best-known uma bomba XML provavelmente é o ataque exponencial Expansion Entity.

Dentro de uma documento tipo definição XML (DTD), você pode definir seus próprio entidades, essencialmente atuam como macros de substituição de seqüência. Por exemplo, você pode adicionar esta linha para seu DTD para substituir todas as ocorrências da seqüência de caracteres &companyname; com “ Contoso Inc. ”:

<!ENTITY companyname "Contoso Inc.">

Você também pode aninhar entidades, como este:

<!ENTITY companyname "Contoso Inc.">
<!ENTITY divisionname "&companyname; Web Products Division">

Enquanto a maioria dos desenvolvedores estão familiarizados com usando arquivos DTD externos, também é possível incluir embutido DTDs juntamente com os dados de XML. Simplesmente definir o DTD diretamente no <! DOCTYPE > declaração em vez de usar <! DOCTYPE > para se referir a um arquivo DTD externo:

<?xml version="1.0"?>
<!DOCTYPE employees [
  <!ELEMENT employees (employee)*>
  <!ELEMENT employee (#PCDATA)>
  <!ENTITY companyname "Contoso Inc.">
  <!ENTITY divisionname "&companyname; Web Products Division">
]>
<employees>
  <employee>Glenn P, &divisionname;</employee>
  <employee>Dave L, &divisionname;</employee>
</employees>

Um invasor pode agora aproveitar essas três propriedades de XML (substituição entidades, entidades aninhadas e embutido DTDs) para elaborar uma bomba XML mal-intencionado. O invasor grava um documento XML com entidades aninhadas como o exemplo anterior, mas em vez de apenas um nível profunda, he aninha aninhamento suas entidades muitos níveis de profundidade, como mostrado aqui:

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol "lol">
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

Observar que este XML é bem formado e válido de acordo com as regras o DTD. Quando um analisador XML carrega este documento, ele vê que inclui um elemento raiz, “ lolz ”, que contém o texto “ &lol9; ”. No entanto, “ &lol9; ” é uma entidade definida que expande para uma seqüência contendo dez “ &lol8; ” seqüências. Cada “ &lol8; ” seqüência é uma entidade definida expande para dez “ &lol7; ” seqüências e assim por diante. Após todas as expansões de entidade foram processados, este pequeno bloco (< 1 KB) de XML realmente irá conter um bilhão “ lol ” s, ocupando quase 3 GB de memória!  Tente este ataque (às vezes chamado de ataque Laughs bilhões) para si mesmo usando este bloco de código muito simples — ser preparado para eliminar a partir do Gerenciador de tarefas do processo de aplicativo de teste:

void processXml(string xml)
{
    System.Xml.XmlDocument document = new XmlDocument();
    document.LoadXml(xml);
}

Alguns leitores mais esperto podem estar se perguntando neste ponto se é possível criar uma expansão de entidade infinitamente recursing consiste em duas entidades consulte uns aos outros:

<?xml version="1.0"?>
<!DOCTYPE lolz [
  <!ENTITY lol1 "&lol2;">
  <!ENTITY lol2 "&lol1;">
]>
<lolz>&lol1;</lolz>

Esse seria um ataque muito eficaz, mas felizmente não está legal XML e não analisar. No entanto, outra variação da bomba exponencial Entity expansão XML funciona é o ataque desenho quadrática, descoberto pela Amit Klein da Trusteer. Em vez de definir várias entidades pequenas, profundamente aninhadas, o invasor define uma entidade muito grande e muitas vezes se refere a ele:

<?xml version="1.0"?>
<!DOCTYPE kaboom [
  <!ENTITY a "aaaaaaaaaaaaaaaaaa...">
]>
<kaboom>&a;&a;&a;&a;&a;&a;&a;&a;&a;...</kaboom>

Se um invasor define a entidade “ &a; ” como 50.000 caracteres e se refere a que a entidade 50.000 vezes dentro do elemento de “ bUm ” raiz, ele acaba com uma carga de ataque de bomba XML ligeiramente mais 200 KB de tamanho expande 2,5 GB quando analisada. Essa proporção de expansão não é bem como impressionante do como com o ataque exponencial expansão de entidade, mas é ainda o suficiente tirar o processo de análise.

Outro XML bomba descobertas de Klein é o ataque de desenho de atributo. Muitos antigos analisadores XML, incluindo aqueles no runtime do .NET Framework versões 1.0 e 1.1, analisar atributos XML em um O quadrático extremamente ineficiente (2 n ). Criando um documento XML com um grande número de atributos (digamos 100.000 ou mais) para um único elemento, o analisador XML será monopolizar o processador por um longo período de tempo e, portanto, causar uma condição de negação de serviço. No entanto, essa vulnerabilidade foi fixo no .NET Framework versões 2.0 e posterior.

Ataques externos de entidade

Em vez de definir seqüências de caracteres de substituição de entidade como constantes, também é possível defini-los para que seus valores são puxados de URIs externos:

<!ENTITY stockprice SYSTEM    "https://www.contoso.com/currentstockprice.ashx">

Enquanto o comportamento exato depende a implementação de analisador XML específica, a intenção é que toda vez que o analisador XML encontra a entidade “ &stockprice; ” o analisador irá fazer uma solicitação para www.contoso.com/currentstockprice.ashx e substitua a resposta recebida do que a solicitação para a entidade stockprice. Sem dúvida, é um recurso interessante e útil de XML, mas também permite alguns ataques esperto.

A maneira mais simples de abusar funcionalidade entidade externa é enviar o analisador XML para um recurso que nunca retornará; isto é, para enviá-la em um infinito aguardar loop. Por exemplo, se um invasor tivesse controle de adatum.com servidor, ele poderia configurar um arquivo de manipulador HTTP genérico em http://adatum.com/dos.ashx como segue:

using System;
using System.Web;
using System.Threading;

public class DoS : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        Thread.Sleep(Timeout.Infinite);
    }

    public bool IsReusable { get { return false; } }
}

Em seguida, ele poderia criar uma entidade mal-intencionado que apontava para http://adatum.com/dos.ashx e quando o analisador XML lê o arquivo XML, o analisador seria travar. No entanto, isso não é um ataque especialmente eficaz. O ponto de um ataque DoS é consumir recursos para que eles não estão disponíveis para usuários legítimos do aplicativo. Nossos exemplos anteriores de bombs exponencial Expansion Entity e quadrática desenho XML causou o servidor para usar grandes quantidades de memória e tempo de CPU, mas este exemplo não. Tudo o que realmente consome esse ataque é um único thread de execução. Let’s melhorar esse ataque (da perspectiva do invasor), forçando o servidor para consumir alguns recursos:

public void ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    byte[] data = new byte[1000000];
    for (int i = 0; i < data.Length; i++) { data[i] = (byte)’A’; }
    while (true)
    {
        context.Response.OutputStream.Write(data, 0, data.Length);
        context.Response.Flush();
    }
}

Este código irá escrever um número infinito de ‘ A ’ caracteres (um milhão em um tempo) para a resposta de fluxo e chew até uma enorme quantidade de memória em um tempo muito curto. Se o invasor é impossível ou relutando configurar uma página de seu proprietário para essa finalidade — talvez ele não deseja deixar um rastro de evidências que aponta para ele — em vez disso, ele pode apontar entidade externa para um recurso muito grande em um site de terceiros. Downloads de arquivo ou filme podem ser especialmente eficazes para essa finalidade; por exemplo, o download da versão beta do Visual Studio 2010 Professional é mais de 2 GB.

Outra variação desse ataque inteligente é apontar uma entidade externa em um destino do servidor intranet recursos. Descoberta dessa técnica de ataque é creditada Steve Orrin da Intel. Essa técnica exige o invasor tenha conhecimento interno de sites da intranet acessíveis pelo servidor, mas se um ataque de recursos de intranet pode ser executado, ele pode ser especialmente eficaz porque o servidor está gastando seus próprios recursos (tempo do processador, largura de banda e memória) para atacar o próprio ou servidores seus irmão na mesma rede.

Como se proteger contra XML Bombs

A maneira mais fácil se defender contra todos os tipos de ataques de entidade XML é simplesmente desativar completamente o uso de esquemas DTD embutidos nos objetos de análise do XML. Este é um aplicativo simples do princípio de redução da superfície de ataque: Se você não estiver usando um recurso, desativá-la para que os invasores não conseguirão abusá-lo.

Versões do .NET Framework 3.5 e versões anterior, comportamento de análise de DTD é controlado pela propriedade Boolean ProhibitDtd encontrada nas classes System.Xml.XmlTextReader e System.Xml.XmlReaderSettings. Defina esse valor para true para desabilitar embutido DTDs completamente:

XmlTextReader reader = new XmlTextReader(stream);
reader.ProhibitDtd = true;

ou

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = true;
XmlReader reader = XmlReader.Create(stream, settings);

O valor padrão de ProhibitDtd em XmlReaderSettings é true, mas o valor padrão de ProhibitDtd em XmlTextReader é false, que significa que você tem explicitamente definido para true para desabilitar embutido DTDs.

No .NET Framework versão 4.0 (em beta no momento da redação deste artigo), o comportamento de análise de DTD foi alterado. A propriedade ProhibitDtd foi substituída nova propriedade DtdProcessing. Você pode definir essa propriedade como proibir (o valor padrão) para fazer com que o runtime para lançar uma exceção se um <! DOCTYPE > elemento está presente no XML:

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Prohibit;
XmlReader reader = XmlReader.Create(stream, settings);

Como alternativa, você pode definir a propriedade DtdProcessing ignorar, não lançará uma exceção no encontrando um <! DOCTYPE > elemento mas será simplesmente ignorar e não o processo. Finalmente, você pode definir DtdProcessing para análise se desejar permitir e processar DTDs embutido.

Se você realmente quiser analisar DTDs, você deve tomar algumas etapas adicionais para proteger seu código. A primeira etapa é limitar o tamanho de entidades expandidos. Lembre-se de que os ataques que abordei funcionam Criando entidades que expandem seqüências enormes e forçar o analisador consumir grandes quantidades de memória. Definindo a propriedade MaxCharactersFromEntities do objeto XmlReaderSettings, você pode capitular o número de caracteres que podem ser criados por meio de expansões de entidade. Determinar um máximo razoável e defina a propriedade adequadamente. Eis um exemplo:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1024;
XmlReader reader = XmlReader.Create(stream, settings);

Como se proteger contra ataques externos de entidade

Neste ponto, podemos protegeu esse código, de modo que é muito menos vulnerável a bombs XML, mas ainda não podemos ainda endereçados perigos impostos por entidades externas mal-intencionadas. Você pode melhorar sua resistência contra esses ataques se você personalizar o comportamento do XmlReader alterando seu XmlResolver. XmlResolver objetos são usados para resolver referências externas, incluindo entidades externas. Instâncias de XmlTextReader, bem como instâncias XmlReader retornadas de chamadas para XmlReader.Create, são preenchidas com padrão XmlResolvers (realmente XmlUrlResolvers). Você pode impedir que XmlReader resolvendo entidades externas permitindo ainda ele resolver entidades embutido, definindo a propriedade XmlResolver do XmlReaderSettings para nulo. Esta é a redução da superfície de ataque no trabalho novamente; se você não precisa de capacidade, desativá-la:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1024;
settings.XmlResolver = null;
XmlReader reader = XmlReader.Create(stream, settings);

Se essa situação não se aplicar a você — se você realmente, realmente precisa resolver entidades externas — esperança todos não é perdida, mas você tiver um pouco mais trabalho a fazer. Para tornar XmlResolver mais resistente a ataques de negação de serviço, você precisa alterar seu comportamento de três maneiras. Primeiro, você precisa definir um tempo limite de solicitação para impedir ataques de atraso infinito. Segundo, você precisa limitar a quantidade de dados que irá recuperar. Finalmente, como uma medida de defesa em profundidade, você precisa restringir o XmlResolver de recuperação de recursos no host local. Você pode fazer tudo isso criando uma classe XmlResolver personalizada.

O comportamento que você deseja modificar é regido pelo método XmlResolver GetEntity. Criar uma nova classe que XmlSafeResolver derivado de XmlUrlResolver e substituir o método GetEntity como segue:

class XmlSafeResolver : XmlUrlResolver
{
    public override object GetEntity(Uri absoluteUri, string role, 
        Type ofObjectToReturn)
    {

    }
}

O comportamento padrão do método XmlUrlResolver.GetEntity parece algo como o código a seguir, você pode usar como ponto de partida para a sua implementação:

public override object GetEntity(Uri absoluteUri, string role, 
    Type ofObjectToReturn)
{
    System.Net.WebRequest request = WebRequest.Create(absoluteUri);
    System.Net.WebResponse response = request.GetResponse();
    return response.GetResponseStream();
}

A primeira alteração é aplicar valores de tempo limite quando fazendo a solicitação e quando ler a resposta. O System.NET.WebRequest e classes System.IO.Stream fornecem suporte inerente para tempos limite. No código de exemplo mostrado de Figura 1, eu simplesmente codificar o valor de tempo limite, mas você pode facilmente expor uma propriedade Timeout pública na classe XmlSafeResolver se você desejar configurabilidade maior.

Figura 1 Timeout Configurando valores

private const int TIMEOUT = 10000;  // 10 seconds

public override object GetEntity(Uri absoluteUri, string role, 
   Type ofObjectToReturn)
{
    System.Net.WebRequest request = WebRequest.Create(absoluteUri);
    request.Timeout = TIMEOUT;

    System.Net.WebResponse response = request.GetResponse();
    if (response == null)
        throw new XmlException("Could not resolve external entity");

    Stream responseStream = response.GetResponseStream();
    if (responseStream == null)
        throw new XmlException("Could not resolve external entity");
    responseStream.ReadTimeout = TIMEOUT;
    return responseStream;
}

A próxima etapa é a quantidade máxima de dados recuperados na resposta capitular. Não há nenhuma propriedade “ MaxSize ” ou equivalente para a classe Stream, para que você precise implementar essa funcionalidade você mesmo. Para fazer isso, você pode ler dados de resposta fluxo um bloco uma vez e copiar em um cache local de fluxo. Se o número total de bytes lidos do fluxo de resposta excede um limite predefinido (novamente codificados para simplicidade somente), você parar a leitura do fluxo e lançar uma exceção (consulte do Figura 2).

Figura 2 controlada a quantidade máxima de dados recuperados

private const int TIMEOUT = 10000;                   // 10 seconds
private const int BUFFER_SIZE = 1024;                // 1 KB 
private const int MAX_RESPONSE_SIZE = 1024 * 1024;   // 1 MB

public override object GetEntity(Uri absoluteUri, string role, 
   Type ofObjectToReturn)
{
    System.Net.WebRequest request = WebRequest.Create(absoluteUri);
    request.Timeout = TIMEOUT;

    System.Net.WebResponse response = request.GetResponse();
    if (response == null)
        throw new XmlException("Could not resolve external entity");

    Stream responseStream = response.GetResponseStream();
    if (responseStream == null)
        throw new XmlException("Could not resolve external entity");
    responseStream.ReadTimeout = TIMEOUT;

    MemoryStream copyStream = new MemoryStream();
    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead = 0;
    int totalBytesRead = 0;
    do
    {
        bytesRead = responseStream.Read(buffer, 0, buffer.Length);
        totalBytesRead += bytesRead;
        if (totalBytesRead > MAX_RESPONSE_SIZE)
            throw new XmlException("Could not resolve external entity");
        copyStream.Write(buffer, 0, bytesRead);
    } while (bytesRead > 0);

    copyStream.Seek(0, SeekOrigin.Begin);
    return copyStream;
}

Como alternativa, você pode quebrar a classe Stream e implementar o limite de verificação diretamente no método Read substituído (consulte do Figura 3). Isso é uma implementação mais eficiente como salvar memória extra alocada para MemoryStream em cache no exemplo anterior.

Figura 3 definindo um tamanho-limitada a classe de invólucro de fluxo

class LimitedStream : Stream
{
    private Stream stream = null;
    private int limit = 0;
    private int totalBytesRead = 0;

    public LimitedStream(Stream stream, int limit)
    {
        this.stream = stream;
        this.limit = limit;
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        int bytesRead = this.stream.Read(buffer, offset, count);
        checked { this.totalBytesRead += bytesRead; }
        if (this.totalBytesRead > this.limit)
            throw new IOException("Limit exceeded");
        return bytesRead;
    }

    ...
}

Agora, simplesmente encapsular o fluxo retornado de WebResponse.GetResponseStream em um LimitedStream e retornar o LimitedStream do método GetEntity (consulte do Figura 4).

Figura 4 usando LimitedStream em GetEntity

private const int TIMEOUT = 10000; // 10 seconds
private const int MAX_RESPONSE_SIZE = 1024 * 1024; // 1 MB

public override object GetEntity(Uri absoluteUri, string role, Type
ofObjectToReturn)
{
    System.Net.WebRequest request = WebRequest.Create(absoluteUri);
    request.Timeout = TIMEOUT;

    System.Net.WebResponse response = request.GetResponse();
    if (response == null)
        throw new XmlException("Could not resolve external entity");

    Stream responseStream = response.GetResponseStream();
    if (responseStream == null)
        throw new XmlException("Could not resolve external entity");
    responseStream.ReadTimeout = TIMEOUT;

    return new LimitedStream(responseStream, MAX_RESPONSE_SIZE);
}

Finalmente, adicione uma medida de defesa em profundidade mais bloqueando entidade resolução de URIs resolver .esta de (de consulte do Figura 5) host local inclui URIs iniciando com http://localhost, http://127.0.0.1 e file:// URIs. Observe que isso também impede uma vulnerabilidade de divulgação de informações muito desagradável em que os invasores podem elaborar entidades apontando para file://resources, o conteúdo da qual é então levadas recuperado e gravado no documento XML pelo analisador.

Figura 5 bloqueio resolução de entidade de host local

public override object GetEntity(Uri absoluteUri, string role,
    Type ofObjectToReturn)
{
    if (absoluteUri.IsLoopback)
        return null;
    ...
}

Agora que você tenha definido um XmlResolver mais seguro, você precisa aplicar a XmlReader. Explicitamente instanciar um objeto XmlReaderSettings, defina a propriedade XmlResolver para uma instância de XmlSafeResolver e usar o XmlReaderSettings ao criar XmlReader, como mostrado aqui:

XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = new XmlSafeResolver();
settings.ProhibitDtd = false;   // comment out if .NET 4.0 or later
settings.DtdProcessing = DtdProcessing.Parse;  // comment out if 
                                               // .NET 3.5 or earlier
settings.MaxCharactersFromEntities = 1024;
XmlReader reader = XmlReader.Create(stream, settings);

Considerações adicionais

É importante observar que em muitas classes System.XML, se um XmlReader não for fornecido explicitamente a um objeto ou um método e implicitamente um é criado para ele no código de estrutura. Isso criadas implicitamente XmlReader não terá qualquer das defesas adicionais especificadas neste artigo e ser vulnerável a ataques. O primeiro trecho de código neste artigo é um ótimo exemplo desse comportamento:

void processXml(string xml)
{
    System.Xml.XmlDocument document = new XmlDocument();
    document.LoadXml(xml);
}

Esse código é vulnerável completamente para todos os ataques descritos neste artigo. Para melhorar esse código, explicitamente criar um XmlReader com configurações apropriadas (ou desativar o DTD in-line análise ou especifica uma classe resolvedor mais segura) e usar a sobrecarga de XmlDocument.Load(XmlReader) em vez de XmlDocument.LoadXml ou quaisquer outras sobrecargas de XmlDocument.Load, como mostrado no do Figura 6.

Figura 6 aplicando Entity seguro analisar configurações para XmlDocument

void processXml(string xml)
{
    MemoryStream stream =
        new MemoryStream(Encoding.Default.GetBytes(xml));
    XmlReaderSettings settings = new XmlReaderSettings();

    // allow entity parsing but do so more safely
    settings.ProhibitDtd = false;
    settings.MaxCharactersFromEntities = 1024;
    settings.XmlResolver = new XmlSafeResolver();

    XmlReader reader = XmlReader.Create(stream, settings);
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);
}

XLinq é um pouco mais seguro em suas configurações padrão; XmlReader criado por padrão para System.Xml.Linq.XDocument permite análise DTD, mas define MaxCharactersFromEntities para 10,000,000 automaticamente e proíbe resolução entidade externa. Se você explicitamente fornece um XmlReader para XDocument, certifique-se de aplicar as configurações defensivas descritas anteriormente.

Conclusão

Expansão de entidade XML é um recurso poderoso, mas facilmente pode ser explorada por um invasor negar serviço para seu aplicativo. Certifique-se de siga o princípio de redução da superfície de ataque e desativar expansão da entidade se não exigem o seu uso. Caso contrário, aplica defesas apropriadas para limitar a quantidade máxima de tempo e memória que seu aplicativo pode gastar nele.

Bryan Sullivan é um gerente de programa de segurança para a equipe de SDL Microsoft, especializado no aplicativo Web e .NET problemas de segurança. Ele é autor de “ AJAXSecurity ” (Addison-Wesley, 2007).