GraphQL est une technologie récente et largement utilisée pour construire des API modernes et puissantes. Cependant, cette technologique n’est pas toujours bien configurée par les équipes de développement, ce qui entraîne des risques en matière de sécurité informatique. Comment sécuriser GraphQL ? Quelles sont les bonnes pratiques à mettre en oeuvre ? C’est ce que nous allons étudier ensemble dans cet article de blog.
GraphQL (Graph Query Language) est un terme qui décrit à la fois un langage de requêtes (DQL pour Data Query Language) et un interprétateur de ce langage. GraphQL a été créé en 2012 par Facebook, et publié en tant que projet open-source en 2015.
GraphQL est une alternative puissante aux modèles d’API REST et SOAP. L’intérêt de GraphQL par rapport à REST ou SOAP sera présenté de manière plus générale dans un futur article de ce blog, mais peut se résumer en la possibilité de faire des requêtes très riches et donc moins nombreuses, ce qui est un point fort pour des API utilisées par des applications mobiles.
GraphQL fait l’objet d’implémentations réalisées par des tiers. Par exemple, le projet GraphQL-Go, qui implémente GraphQL dans le langage Go, est concerné par 2 CVE au moment de la rédaction de cet article.
Les configurations par défaut de GraphQL ne sont pas sécurisées, par exemple :
Ces éléments sont en général mal maîtrisé par les équipes de développement qui découvrent GraphQL. Or, cette technologie est encore assez récente et le niveau de maîtrise général de cette technologie est en cours de progression.
L’identification de la présence de GraphQL est simple, et peut se faire en détectant la syntaxe GraphQL dans des requêtes, ou en détectant la présence d’URI comme :
GraphQL fait l’objet de scripts d’analyse simples à manipuler
Si une application qui utilise une base SQL peut être auditée à l’aide d’un logiciel comme SQLmap, les applications qui utilisent une API GraphQL peuvent être également testées à l’aide d’un logiciel similaire nommé GraphQLmap.
Par défaut, une API GraphQL ne présente pas de mécanisme d’authentification ou de contrôle d’accès. Cela a pour impact de permettre à un utilisateur malveillant d’effectuer des requêtes construites pour extraire des informations qui ne devraient pas lui être permises.
De même, certaines ressources de l’API peuvent être requises pour les administrateurs de l’application, mais masquées pour les utilisateurs plus classiques. Ce mécanisme doit dans ce cas être implémenté dans l’application et ne sont pas gérés par défaut par GraphQL.
Le site Apollo fournit des exemples de documentation pour résoudre ces éléments sur https://www.apollographql.com/docs/apollo-server/security/authentication/#authorization-methods.
L’introspection est un mécanisme très pratique dans une phase de développement, qui permet notamment de récupérer le schéma d’une API GraphQL.
Pour l’exploiter, il suffit d’envoyer la requête suivante à une API GraphQL :
{__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}
Cette requête renvoie alors les types, champs et arguments du schéma, ce qui permet de comprendre l’organisation générale de la base de données utilisée et comment détourner l’API GraphQL pour dérober des informations.
L’introspection doit ainsi être désactivée sur les environnements de production. Le site d’Apollo donne d’excellents conseils sur le sujet : https://www.apollographql.com/blog/graphql/security/why-you-should-disable-graphql-introspection-in-production/.
Par défaut, GraphQL donne beaucoup de détails dans ses messages d’erreurs. Ceci est particulièrement intéressant pour un attaquant, car cela fournit un guide pour résoudre des erreurs de requêtes et former des requêtes valides mais dangereuses pour l’application.
Le mieux est alors d’enregistrer les erreurs dans un journal consulté par les développeurs, mais de les rendre moins verbeux pour les utilisateurs.
Ceci peut être fait par des bibliothèques comme https://github.com/kadirahq/graphql-errors.
La technologie GraphQL agit comme une passerelle avec les éléments de la base de données. En conséquence, si l’application développée envoie les paramètres de l’API GraphQL sans vérifier leur format, cela peut mener à des injections SQL ou NoSQL selon la nature de la base de données interrogée.
Il est donc très important de contrôler les éléments qui sont envoyés à l’API, afin d’éviter de provoquer un vol de données.
L’OWASP (Open Web Application Security Project) fournit de nombreux conseils sur le sujet sur https://cheatsheetseries.owasp.org/cheatsheets/GraphQL_Cheat_Sheet.html#input-validation.
Cela passe par exemple par :
GraphQL permet de construire des requêtes particulièrement complexes, dont les objets peuvent s’imbriquer les uns dans les autres. Cette complexité peut parfois être utilisée par un attaquant pour provoquer des requêtes lentes et donc un déni de service.
Dans l’exemple ci-dessous, l’API GraphQL permet de requêter les Messages d’un Thread, ou les Threads d’un Message.
Un attaquant peut alors construire une requête très coûteuse en temps et en ressources pour l’application, qui provoquera un déni de service : l’attaquant demande à récupérer les 99999 Messages d’un Thread, puis de récupérer pour chaque Message le Thread associé, et les 99999 Messages de chacun de ces Threads, etc.
Il est alors possible de neutraliser ce type d’attaque en ajoutant des règles de validation, comme sur Apollo avec la documentation suivante https://www.apollographql.com/blog/graphql/security/securing-your-graphql-api-from-malicious-queries/#depth-limiting.
La sécurité informatique est un domaine complexe où il est important de s’entourer d’experts, en particulier pour les équipes de développement.
Cyberwatch propose des services de tests d’intrusion, qui couvrent notamment les technologies GraphQL. Nos experts seront ravis de vous accompagner sur vos projets de sécurité.
Cyberwatch propose également un logiciel de détection, priorisation, et correction des vulnérabilités, qui peut vous aider à suivre les CVE de vos applications.
N’hésitez pas à nous contacter sur le formulaire dédié pour demander des informations sur nos services et produits !