Leaders Logo

Controle de Profundidade em APIs GraphQL com .NET: Uma Abordagem Segura para Mitigação de Ataques DoS

Introdução ao GraphQL

O GraphQL é uma linguagem de consulta desenvolvida pelo Facebook, que permite que os clientes solicitem exatamente os dados de que precisam, minimizando a sobrecarga de dados desnecessários (GRAPHQL, 2025). Ao contrário das APIs REST, onde os endpoints são fixos, no GraphQL os clientes podem definir a estrutura da resposta, resultando em maior flexibilidade e eficiência (SABBAG FILHO, 2025). Essa flexibilidade, no entanto, traz consigo desafios significativos, especialmente em termos de segurança e desempenho. Neste artigo, discutiremos como implementar controles de profundidade em APIs GraphQL usando .NET, visando mitigar ataques de negação de serviço (DoS).

Desafio de Segurança em APIs GraphQL

Um dos principais desafios de segurança nas APIs GraphQL é a vulnerabilidade a ataques de negação de serviço (DoS). Devido à sua natureza flexível, um cliente pode fazer solicitações que exigem uma quantidade excessiva de recursos do servidor, resultando em degradação de desempenho ou até mesmo interrupções do serviço (MCFADDEN et al., 2024). É crucial implementar medidas de controle para mitigar esses riscos e garantir que a API permaneça responsiva e segura. Além disso, a complexidade das consultas pode aumentar exponencialmente, tornando difícil a previsão do impacto no desempenho. Portanto, é essencial que os desenvolvedores entendam essas vulnerabilidades e implementem soluções adequadas.

Controle de Profundidade em Consultas

Uma abordagem para mitigar ataques DoS é o controle de profundidade nas consultas GraphQL (MOLLER et al., 2024). Esse controle limita a profundidade das consultas aninhadas, evitando que um cliente faça solicitações que possam causar uma carga excessiva no servidor. Por exemplo, se uma consulta permitir um nível de profundidade de 5, um cliente não poderá fazer uma solicitação que aninhe consultas a mais de 5 níveis. Essa técnica é fundamental para prevenir que consultas maliciosas ou malformadas sobrecarreguem o sistema. Além de limitar a profundidade, é importante considerar o balanceamento entre funcionalidade e segurança, garantindo que usuários legítimos possam acessar os dados que precisam sem obstáculos desnecessários.

Imagem SVG do Artigo

Controle de Profundidade com .NET

Para implementar o controle de profundidade em uma API GraphQL usando .NET, podemos usar o pacote GraphQL.NET (GRAPHQL.NET, 2025). A seguir, apresentamos um exemplo de como configurar esse controle:

using GraphQL;
using GraphQL.Types;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<ISchema, MySchema>();
        services.AddGraphQL(options =>
        {
            options.EnableMetrics = false;
            options.ExposeExceptions = false;
            options.FieldMiddleware.Use<DepthControlMiddleware>();
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseGraphQL<ISchema>();
    }
}

public class DepthControlMiddleware : IFieldMiddleware
{
    public async Task<object> Resolve(ResolveFieldContext context, FieldMiddlewareDelegate next)
    {
        var depth = GetQueryDepth(context);
        if (depth > 5) // Limite de profundidade
        {
            throw new Exception("Consulta muito profunda. Limite de profundidade de 5 excedido.");
        }

        return await next(context);
    }

    private int GetQueryDepth(ResolveFieldContext context)
    {
        // Lógica para calcular a profundidade da consulta
        // Retorna um inteiro representando a profundidade
    }
}

Cálculo da Profundidade da Consulta por Nível de Aninhamento

Para calcular a profundidade de uma consulta GraphQL, você pode implementar uma função que percorre a árvore de consulta e conta o nível de aninhamento. Um exemplo simples pode ser visto abaixo:

private int GetQueryDepth(ResolveFieldContext context)
{
    int depth = 0;
    var currentField = context.FieldAst;

    while (currentField != null)
    {
        depth++;
        currentField = currentField.SelectionSet?.Selections.OfType<Field>()
        .FirstOrDefault()?.SelectionSet;
    }

    return depth;
}

Cálculo da Complexidade da Consulta com Base nos Pesos dos Campos

Outra abordagem é utilizar um middleware para controlar a complexidade das consultas com base nos campos utilizados. Cada campo recebe um peso, e se o peso total da consulta ultrapassar um limite predefinido, ela é rejeitada. A implementação é semelhante ao controle por profundidade, com a diferença de considerar pesos específicos por campo.

public class ComplexityControlMiddleware : IFieldMiddleware
{
    private const int MaxComplexity = 100;

    public async Task<object> Resolve(ResolveFieldContext context, FieldMiddlewareDelegate next)
    {
        var complexity = CalculateComplexity(context);
        if (complexity > MaxComplexity)
        {
            throw new Exception("Complexidade da consulta excedida.");
        }

        return await next(context);
    }

    private int CalculateComplexity(ResolveFieldContext context)
    {
        // Lógica para calcular a complexidade da consulta
        // Retorna um inteiro representando a complexidade total
    }
}

O próximo passo é implementar o cálculo da complexidade considerando os pesos de cada campo. Veja a seguir um exemplo simples:

private int CalculateComplexity(ResolveFieldContext context)
{
    int complexity = 1; // Peso padrão para o campo atual

    foreach (var selection in context.FieldAst.SelectionSet.Selections)
    {
        if (selection is Field field)
        {
            complexity += CalculateFieldComplexity(field);
        }
    }

    return complexity;
}

private int CalculateFieldComplexity(Field field)
{
    // Atribuir pesos a campos específicos
    switch (field.Name.Value)
    {
        case "user":
            return 5; // Exemplo de peso
        case "posts":
            return 3; // Exemplo de peso
        default:
            return 1; // Peso padrão
    }
}

Testando a Implementação

Após implementar o controle de profundidade e limites de complexidade, é importante realizar testes para garantir que as proteções funcionem conforme o esperado. Você pode usar ferramentas de teste de carga para simular várias solicitações e verificar se a API responde adequadamente sem falhas ou degradação de desempenho. Testes de estresse também são recomendados para avaliar como a API se comporta sob condições extremas, ajudando a identificar pontos fracos antes que se tornem problemas em produção.

Conclusão

O controle de profundidade e a limitação de complexidade são abordagens eficazes para proteger APIs GraphQL contra ataques DoS. Ao implementar essas medidas em suas aplicações .NET, você não apenas melhora a segurança, mas também garante uma experiência de usuário mais estável. Com a crescente adoção do GraphQL, é crucial que os desenvolvedores estejam cientes dos riscos e implementem as melhores práticas para proteger suas APIs. Além disso, a documentação e a educação contínua sobre as práticas de segurança em GraphQL são fundamentais para garantir que a comunidade se mantenha informada sobre as últimas ameaças e soluções.

Referências

  • GRAPHQL. Learn GraphQL. Disponível em: https://graphql.org/learn/. Acesso em: 1 jun. 2025. reference.Description
  • GRAPHQL.NET. GraphQL.NET - Site Oficial. Disponível em: https://dotnetgraphql.com/. Acesso em: 1 jun. 2025. reference.Description
  • SABBAG FILHO, Nagib. API modeling with REST and GraphQL: Case study in. NET projects. Leaders Tec, v. 2, n. 19, 2025. reference.Description
  • MCFADDEN, Shae et al. WENDIGO: Deep Reinforcement Learning for Denial-of-Service Query Discovery in GraphQL. In: 2024 IEEE Security and Privacy Workshops (SPW). IEEE, 2024. p. 68-75. reference.Description
  • MOLLER, Arno; MAKURA, Sheunesu; VENTER, Hein. A Model to Limit Batching Denial of Service Attacks on GraphQL. In: 2024 IST-Africa Conference (IST-Africa). IEEE, 2024. p. 1-11. reference.Description
Sobre o autor