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.
Introduction à GraphQL
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.
Quels sont les principaux risques liés à GraphQL ?
Les implémentations de GraphQL font l’objet de vulnérabilités connues publiées dans la base CVE
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.
GraphQL est une technologie récente dont les configurations par défaut présentent des risques
Les configurations par défaut de GraphQL ne sont pas sécurisées, par exemple :
- L’authentification n’est pas activée et doit être implémentée par les développeurs ;
- Le module d’introspection est activé et permet d’obtenir tout le schéma des requêtes GraphQL.
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.
GraphQL est une technologie dont la présence est simple à identifier
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
- /graphiql
- /graphql.php
- /graphql/console
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.
Revue des principaux risques et des recommandations pour sécuriser une API GraphQL
Sécuriser GraphQL : ajouter des contrôles d’accès ou une authentification
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.
Sécuriser GraphQL : désactiver l’introspection
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/.
Sécuriser GraphQL : réduire la quantité d’informations présentes dans les messages d’erreur
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.
Sécuriser GraphQL : valider les paramètres fournis à l’API pour éviter une injection SQL ou NoSQL
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 :
- l’utilisation de types de données imposés ;
- l’utilisation de schémas pour les paramètres des mutations ;
- l’utilisation d’une liste blanche de caractères acceptés ;
- un rejet systématique des paramètres invalides, sans informations détaillées dans les messages d’erreurs alors renvoyés.
Sécuriser GraphQL : neutraliser les risques de déni de service
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.
Sécuriser GraphQL : réaliser des tests d’intrusion et des scans de vulnérabilités
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 !