Para iniciar, GraphQL é uma linguagem de consulta de API poderosa e flexível que tem ganhado popularidade nos últimos anos devido à sua capacidade de fornecer aos desenvolvedores a flexibilidade de obter exatamente os dados necessários em uma única requisição. No entanto, assim como qualquer tecnologia, também possui suas próprias vulnerabilidades de segurança em GraphQL, nesse artigo vamos comentar sobre 4 delas, e como mitigá-las.
Injeção de consulta
Injeção de consulta é uma vulnerabilidade em que um invasor é capaz de injetar consultas maliciosas no GraphQL para obter acesso não autorizado a dados sensíveis ou realizar operações indesejadas no sistema. Isso pode ocorrer quando o servidor GraphQL não valida ou sanitiza adequadamente os dados de entrada antes de processá-los como parte das consultas.
Um exemplo clássico de injeção de consulta é quando um invasor injeta uma consulta GraphQL com uma lógica de negação no argumento de uma consulta, permitindo-lhe acessar dados que normalmente estariam fora dos limites de sua autorização.
Exemplos:
Request:

Response:

Nesse exemplo, a consulta simplesmente busca as informações do usuário com o ID fornecido. No entanto, se um invasor conseguir injetar uma consulta maliciosa, o invasor poderá obter informações não autorizadas do usuário com ID 2, como a senha, que normalmente não deveria ser acessível.
Request:

No segundo exemplo, a consulta foi atualizada para usar uma variável ($userId) em vez de passar o ID diretamente na consulta. A variável é então fornecida como um argumento na solicitação, juntamente com seu valor correspondente.
Do mesmo modo, ao fazer isso, a consulta se torna imune à injeção de consulta, pois os valores de entrada são validados e tratados corretamente, evitando consultas maliciosas ou não autorizadas.
Além disso, é importante adotar o princípio de “menor privilégio”, garantindo que as consultas GraphQL tenham apenas acesso aos dados estritamente necessários e sejam restritas às permissões de autorização apropriadas para cada usuário.
Negação de serviço (DoS)
Quando essa vulnerabilidade é colocada em prática o invasor realiza consultas complexas e aninhadas, assim é possível que um invasor crie consultas maliciosas que sejam excessivamente complexas ou exigentes em termos de recursos, levando a uma sobrecarga no sistema e resultando em uma negação de serviço.
A falta de um padrão de rate limit no GraphQL também pode ser explorada por um invasor para inundar o servidor com um grande número de requisições em curto espaço de tempo, resultando em uma sobrecarga no sistema e na indisponibilidade do serviço.
Exemplos:
Request:

Response:

Nesse exemplo, a consulta busca todos os usuários, juntamente com suas postagens e comentários. Se um invasor enviar uma consulta com uma grande quantidade de dados ou solicitar operações complexas e aninhadas, o servidor pode ficar sobrecarregado, resultando em uma negação de serviço.
Request:

Nesse exemplo corrigido, foram adicionados limites para restringir o número de registros retornados em cada nível da consulta. Isso limita o impacto de consultas excessivamente pesadas no sistema e ajuda a prevenir ataques de negação de serviço.
Além disso, é recomendado implementar políticas de limite de consulta que considerem fatores como a complexidade da consulta, a profundidade de aninhamento e o tempo de execução. Essas políticas podem ser configuradas com base nas necessidades específicas do sistema e ajudam a evitar abusos e sobrecargas indesejadas.
Controle de Acesso de Registros
A vulnerabilidade de controle de acesso de registros em GraphQL ocorre quando há falhas na implementação adequada de autenticação e autorização, permitindo que usuários não autorizados acessem dados confidenciais. Essa vulnerabilidade pode ocorrer quando não há um sistema de autenticação robusto em vigor, não se verifica corretamente a identidade e as permissões dos usuários antes de fornecer acesso aos registros solicitados.
Exemplos:
Request:

Response:

Nesse exemplo, a consulta busca as informações de um usuário específico (identificado pelo ID “123”), juntamente com suas postagens. No entanto, não há nenhuma verificação de autenticação ou autorização para garantir que o usuário que fez a consulta tenha permissão para acessar essas informações confidenciais.
Para corrigir é necessário verificar a identidade do usuário e suas permissões antes de fornecer acesso aos registros solicitados. Isso pode ser feito por meio de autenticação, como autenticação baseada em token JWT (JSON Web Tokens) ou em sessão, e por meio de um sistema de autorização robusto que concede permissões com base nos papéis e privilégios de cada usuário.
Exposição de Informações Sensíveis
Essa vulnerabilidade ocorre quando dados confidenciais, como senhas, tokens de autenticação ou informações pessoais, são expostos indevidamente nas respostas GraphQL. Isso pode acontecer quando os campos que contêm essas informações são retornados diretamente nas consultas sem a devida proteção.
Além disso, outra situação que pode levar a essa vulnerabilidade é quando erros ou logs detalhados contêm informações sensíveis, como mensagens de erro que revelam dados que deveriam ser confidenciais. Por fim, a falta de criptografia adequada para dados sensíveis pode resultar na exposição dessas informações durante o armazenamento ou a transmissão.
Exemplos:
Request:

Response:

Nesse exemplo, a consulta busca informações do usuário, incluindo campos sensíveis como “password” e “creditCardNumber”. Ao retornar esses campos diretamente na resposta GraphQL, há o risco de exposição indevida de informações confidenciais.
Para corrigir essa vulnerabilidade de exposição de informações sensíveis, é necessário evitar retornar diretamente a esses campos na resposta GraphQL. Aqui está um exemplo corrigido:
Request:
Response:

No exemplo corrigido, apenas os campos não sensíveis, como “name” e “email”, são retornados na resposta GraphQL. Os campos sensíveis, como “password” e “creditCardNumber”, são excluídos da resposta para proteger as informações confidenciais dos usuário, também é importante evitar o retorno direto de dados sensíveis nas respostas GraphQL, adotando técnicas de mascaramento ou substituição, como o uso de hashes de senhas.
Além disso, é essencial garantir que mensagens de erro ou logs detalhados não revelem informações sensíveis. Ao lidar com erros, é recomendado fornecer mensagens de erro genéricas que não exponham detalhes sensíveis ou informações confidenciais. Também é crucial aplicar criptografia adequada para proteger dados sensíveis durante o armazenamento e a transmissão.
Conclusão
Em conclusão, a segurança em GraphQL desempenha um papel fundamental na proteção dos dados sensíveis dos usuários. Portanto, é crucial adotar medidas de segurança adequadas para evitar exposição indevida de informações e ataques maliciosos. Ao compreender as vulnerabilidades existentes, podemos estar mais preparados para enfrentar os desafios que possam surgir ao utilizar dessa tecnologia.
Por fim, é importante seguir as boas práticas de desenvolvimento seguro que foram abordadas durante o artigo. Essas abordagens são fundamentais, especialmente considerando a crescente adoção dessa tecnologia no ambiente de desenvolvimento. A implementação dessas boas práticas é essencial para proteger os sistemas e os usuários em um ambiente GraphQL.
