Ciência e Tecnologia

Como tornar sua implementação do GraphQL mais segura

Quando alguns de nossos desenvolvedores começaram a usar o GraphQL no Strong The One Avance Network, e meu trabalho como parte da equipe principal de segurança da Web analisar as vulnerabilidades potenciais da linguagem. Esperamos que os problemas e as correções que encontramos também ajudem a tornar sua implementação mais segura.

1. Procure configurações seguras

Muitas implementações do GraphQL têm configurações potencialmente inseguras habilitadas por padrão que expandem a superfície de ataque do aplicativo.

Introspecção ou não introspecção

A introspecção é um recurso poderoso do GraphQL que é usado para recuperar informações sobre as consultas, tipos, campos e mutações que ele suporta. É extremamente útil para clientes que consomem endpoints GraphQL, pois fornece documentação abrangente e facilita muito a integração. No entanto, isso vem com um custo. Essa funcionalidade pode ser abusada para recuperar o esquema GraphQL, o que pode ajudar os invasores a procurar vulnerabilidades nos sistemas.

Ter a introspecção do GraphQL em produção geralmente não é considerado uma vulnerabilidade por si só. Às vezes, faz sentido tê-la se a API for pública e deve ser usada por desenvolvedores fora da sua organização. Para APIs privadas, no entanto, pode expor informações confidenciais e expandir a superfície de ataque. Uma regra prática é desabilitar a introspecção na produção, a menos que você tenha uma boa razão para não fazê-lo . Mesmo neste caso, considere permitir a introspecção apenas para solicitações autorizadas.

Além da introspecção, os desenvolvedores podem usar o GraphiQL (GraphQL IDE), que oferece uma interface amigável para explorar o esquema do GraphQL. Embora seja útil no desenvolvimento, representará o mesmo risco que a introspecção se for deixado em produção, portanto, certifique-se de que esteja desabilitado.

Tornar os campos e consultas difusos mais difíceis

Mesmo quando a introspecção estiver desativada, os invasores tentarão confundir valores de campo e consulta para encontrar operações confidenciais que possam ser exploradas ainda mais. O GraphQL facilita essa tarefa com seu recurso interno de sugestões de campo. Quando é cometido um erro de digitação no nome do campo, o GraphQL tentará sugerir um campo existente semelhante ao solicitado.

        "errors":[
            {
                "message":
                "Cannot query field "prices" on type "Plan". Did you mean "price"?",
                "locations":[
                    {
                        "line":1,
                        "column":52
                    }
                ],
                "extensions":{
                    "code":"GRAPHQL_VALIDATION_FAILED"
                }
            }
        ],
        "data":null

Este é um erro típico retornado do terminal GraphQL ao tentar solicitar um campo (neste caso, preços) que não existe no esquema. O recurso de sugestão de campo do GraphQL revela que o nome real do campo é preço.

Isso pode ser aproveitado para enumerar o esquema GraphQL e revelar nomes de campos confidenciais. Portanto, você deve considerar desabilitar esse recurso para APIs privadas se sua implementação do GraphQL oferecer suporte a isso.

Cuidado com erros excessivos

Os erros detalhados do GraphQL ajudam os desenvolvedores a identificar com precisão os problemas no desenvolvimento. No entanto, as mensagens de erro padrão são muito detalhadas e podem representar um risco de segurança ao divulgar informações confidenciais sobre sua infraestrutura de back-end e expor implementações vulneráveis. Portanto, você nunca deve executar o GraphQL no modo de depuração em produção. Em vez disso, tenha um middleware para consumir esses erros detalhados e rastreamentos de pilha, registre-os com segurança e retorne erros amigáveis ​​aos usuários finais.

2. Proteja-se contra ataques de negação de serviço

Uma das maneiras mais comuns de mitigar os ataques DoS na camada de aplicativo é limitando as solicitações aos endpoints da API de endereços IP específicos. Isso evita que a API seja inundada com solicitações, esgotando os recursos do sistema e tornando-se inacessível para usuários normais. Embora as solicitações de limitação de taxa para o endpoint do GraphQL também sejam importantes e devam ser implementadas, raramente serão suficientes para evitar ataques DoS. Com o GraphQL, uma única consulta bem elaborada pode derrubar todo o servidor. Portanto, você precisa de medidas de segurança adicionais para garantir que seu sistema permaneça disponível.

Implementar verificações de profundidade máxima

A flexibilidade do GraphQL permite que os clientes criem consultas complexas e aninhadas, obtendo assim o conjunto de dados exato de que precisam. O problema, no entanto, é que muitos esquemas GraphQL têm gráficos cíclicos que podem ser abusados ​​em consultas maliciosas. Vejamos uma consulta de exemplo profundamente aninhada:

        query circularQuery {
            product {
                plans {
                    product {
                        plans {
                            product {
                                # and so on...
                            }
                        }
                    }
                }
            }
        }

Cada novo nível de aninhamento aumenta exponencialmente o tamanho da resposta, portanto, uma consulta suficientemente profunda pode esgotar os recursos do servidor e torná-lo indisponível. Você pode evitar isso limitando a profundidade da consulta do GraphQL. Isso exigirá uma implementação personalizada, pois geralmente não é suportado nativamente pelo GraphQL. Defina a profundidade para um número razoável que não cause dificuldades para seus consumidores de API:

        "errors":[
            {
                "message":"operation has depth 19, which exceeds the limit of 6",
                "extensions":{
                    "code":"DEPTH_LIMIT_EXCEEDED"
                }
            }
        ],
        "data":null

Exemplo da proteção de aninhamento implementada na API GraphQL. O erro mostra que a consulta foi rejeitada porque seu limite de profundidade foi excedido.

Considere a complexidade da consulta

Ter proteção de aninhamento pode não ser suficiente para evitar que consultas complexas causem problemas de segurança. Certos campos podem retornar mais nós do que outros, tornando-os computacionalmente caros. É aqui que a análise de custo de consulta entra em ação. Atribua valores de custo a diferentes campos e rejeite a consulta se a complexidade exceder o limite:

        "errors":[
            {
                "message":"operation has complexity 312, which exceeds the limit of 160",
                "extensions":{
                    "code":"COMPLEXITY_LIMIT_EXCEEDED"
                }
            }
        ],
        "data":null

Erro retornado da API GraphQL que possui verificações de complexidade de consulta implementadas, indicando que a consulta enviada na solicitação excedeu a complexidade permitida e, portanto, foi rejeitada.

As verificações de complexidade de consulta geralmente exigem mais esforço para implementar e podem não ser necessárias em todos os casos. Antes de escolher essa rota, avalie a complexidade do seu esquema GraphQL e decida se essa prevenção é realmente necessária.

Fique atento a ataques em lote

O GraphQL permite que os usuários enviem várias consultas em uma única solicitação. Isso é chamado de lote de consulta e, apesar de seus muitos benefícios, também pode permitir explorações mais difíceis de detectar. Isso pode resultar não apenas em ataques DoS, mas também em enumeração de objetos, ataques de força bruta e desvio de limite de taxa. WAFs (Web Application Firewalls) ou IDS (Intrusion Detection Systems) podem não detectar esses ataques, pois resultarão apenas em uma única solicitação como esta:

    mutation {
    a1: login(username: "testuser", password: "graphql1") {
	    token
    }
    a2: login(username: "testuser", password: "graphql2") {
	    token
    }
    a3: login(username: "testuser", password: "graphql3") {
	    token
    }
    #....
    }

Este é um exemplo do lote de consultas que pode ser aproveitado para ataque de força bruta de senha.

Algumas técnicas de mitigação podem incluir a limitação do número de operações que podem ser agrupadas em lote e a prevenção de lotes para objetos confidenciais.

Cache seus dados

Embora as técnicas acima resolvam alguns dos problemas de segurança específicos do GrapQL, pode haver situações em que isso não seja suficiente. Isso pode ser um bug na implementação ou um cenário normal de uso de API que você não pensou. Considere o exemplo abaixo:

        query plans (product: [STRONG, STRONG, STRONG, STRONG....]) {
            id
            price
            currency
        }

O mesmo valor de campo é passado várias vezes, resultando em grandes quantidades de consultas de banco de dados. Para evitar que esses tipos de problemas aconteçam, considere implementar o armazenamento em cache para suas consultas. Isso evitará ataques DoS e aumentará a eficiência de sua API GraphQL, limitando o consumo de recursos.

Cuidado com as outras vulnerabilidades da API

Embora o GraphQL tenha seus próprios problemas de segurança específicos que precisam ser resolvidos, não é diferente de outras tecnologias em termos de segurança de API. Também é propenso a injeções, IDORs, falhas de autenticação e autorização e outras vulnerabilidades de segurança comuns. É importante seguir práticas de desenvolvimento seguras e fazer testes de segurança adequados antes de implantar sua API na produção.

Não se esqueça do monitoramento

É sempre importante monitorar seus sistemas e o endpoint GraphQL não é exceção. Mesmo as implementações mais completas podem causar problemas, então fique de olho em:

  • Desempenho da consulta . Existem sinais de consultas lentas que precisam ser otimizadas?
  • Atrasos de resposta significativos . Quanto tempo leva para o endpoint responder?
  • Erros e falhas . Existem erros ou falhas de validação ou análise de consulta no banco de dados?

Monitorar seu endpoint GraphQL não apenas ajudará a identificar problemas de segurança, mas também identificará possíveis gargalos em seu pipeline de busca de dados para que você possa otimizar seu endpoint para obter melhor desempenho.

Mostrar mais

Artigos relacionados

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Botão Voltar ao topo