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