Sécuriser ses APIs REST et GraphQL : guide complet 2026
Les APIs sont devenues la surface d'attaque numéro un des applications modernes. En 2026, elles représentent le vecteur de compromission le plus documenté dans les incidents de sécurité majeurs. L'OWASP API Security Top 10 recense les risques spécifiques aux APIs, distincts des vulnérabilités applicatives classiques. Selon le rapport Salt Security 2025, 94 % des organisations ont subi un incident de sécurité lié à leurs APIs au cours des douze derniers mois. Le coût moyen d'une violation liée à une API exposée dépasse 4,5 millions de dollars, sans compter l'atteinte à la réputation. Concevoir des APIs sécurisées n'est pas une option : c'est une exigence non négociable.
Authentification et autorisation : les deux piliers
La confusion entre authentification (AuthN) et autorisation (AuthZ) est à l'origine de nombreuses failles critiques. L'authentification répond à la question : qui es-tu ? Elle établit l'identité de l'appelant. L'autorisation répond à : qu'as-tu le droit de faire ? Elle détermine les actions et ressources accessibles à cette identité. Les deux vérifications sont indépendantes et doivent être appliquées systématiquement.
OAuth2 avec scopes est le standard pour déléguer l'accès aux APIs. Les scopes définissent les permissions accordées à un client. Une API de lecture devrait exiger uniquement un scope read:resource, jamais un scope administrateur. Le principe du moindre privilège s'applique directement : les clients n'obtiennent que les scopes strictement nécessaires à leur fonction. Éviter les scopes trop larges comme * ou admin dans les flows machine-to-machine.
La validation des JWT côté serveur ne se limite pas à vérifier la signature cryptographique. Elle inclut obligatoirement : la vérification de l'expiration (exp), de l'émetteur (iss), de l'audience (aud), et du flag nbf(not before). Un token expiré avec une signature valide doit être rejeté. Ne jamais lire l'algorithme depuis l'en-tête du token — toujours le spécifier explicitement côté serveur pour éviter les attaques de confusion d'algorithme.
Le choix entre API keys et OAuth2 dépend du contexte. Les API keys conviennent aux intégrations simples entre services internes où la rotation est gérée opérationnellement. OAuth2 est préférable dès que l'accès délégué (agir au nom d'un utilisateur) ou des permissions granulaires sont requises. Pour les communications service-à-serviceen environnement sensible, deux approches dominent : le flow Client Credentials d'OAuth2 (avec rotation régulière du secret client) et le mTLS (mutual TLS), où chaque service présente un certificat client vérifié par l'autre partie. Le mTLS offre une garantie cryptographique forte de l'identité du service appelant, indépendante des secrets applicatifs.
Rate limiting et protection contre les abus
Le rate limiting n'est pas une optimisation de performance : c'est une mesure de sécurité fondamentale. Sans limitation, une API exposée peut être exploitée pour du credential stuffing, de l'énumération de ressources, du scraping massif ou des attaques par déni de service applicatif (Layer 7). La lenteur d'une réponse de limitation bien conçue est intentionnelle — elle dégrade l'expérience des attaquants sans impacter les usages légitimes.
Les stratégies de limitation se combinent selon les besoins. La limitation par IP protège contre les attaques volumétriques simples mais est contournable via des réseaux de proxies. La limitation par token est plus précise : chaque client API dispose de quotas indépendants, ce qui permet de protéger les autres clients en cas d'abus d'un seul. La limitation par endpoint adapte les seuils à la sensibilité des routes — un endpoint d'authentification tolère beaucoup moins de tentatives par seconde qu'un endpoint de lecture. La limitation par tenant isole les clients dans les architectures multi-tenant.
Deux algorithmes dominent l'implémentation. Le token bucket maintient un compteur qui se remplit à taux constant et se vide à chaque requête — il autorise des rafales courtes tout en plafonnant le débit moyen. La sliding window calcule le nombre de requêtes dans une fenêtre temporelle glissante, offrant une limitation plus lisse sans autoriser les rafales en début de fenêtre fixe. Les headers X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset et Retry-Afterdoivent être renvoyés pour permettre aux clients légitimes d'adapter leur rythme automatiquement.
Pour les APIs GraphQL, le rate limiting traditionnel par requête est insuffisant : une seule requête peut déclencher des centaines d'opérations en base via des requêtes imbriquées. Trois mécanismes complémentaires s'imposent. Le depth limiting rejette les requêtes dont l'imbrication dépasse un seuil configuré. La complexity analysis attribue un coût à chaque champ et opération, refusant les requêtes dont le coût total excède un budget. Le query whitelisting(ou persisted queries) est l'approche la plus sûre en production : seules les requêtes pré-approuvées sont autorisées.
Validation des entrées et prévention des injections
Toute donnée externe à l'API est potentiellement malveillante. Les paramètres de chemin (path params), les paramètres de requête (query params), le corps de la requête et les headers doivent être validés strictement avant tout traitement. La validation doit être exhaustive : type de données, format, longueur maximale, valeurs autorisées. Un identifiant attendu en UUID doit être rejeté s'il ne correspond pas au format UUID — sans exception.
Le schéma OpenAPI (ex-Swagger) transcende son rôle de documentation pour devenir un contrat de sécurité. En générant la validation automatiquement à partir du schéma — avec des bibliothèques comme express-openapi-validator ou les middlewares de validation intégrés des frameworks — on garantit que toute requête non conforme est rejetée avant d'atteindre la logique métier. Les bibliothèques de validation comme Zod (TypeScript), Joi (Node.js) ou Pydantic (Python) permettent une validation déclarative, lisible et testable.
Les injections NoSQL sont souvent sous-estimées. Avec MongoDB, un champ de login acceptant un objet JSON {"$gt": ""}peut contourner l'authentification si le paramètre n'est pas validé comme une chaîne. Les champs libres — commentaires, descriptions, tags — sont des vecteurs d'injection dans les moteurs de recherche full-text, les systèmes de templates et les générateurs de requêtes dynamiques. La sanitisation ne remplace pas la validation : préférer des requêtes paramétrées et des ORMs qui encapsulent la construction des requêtes.
Pour GraphQL, l'introspection en production est un risque fréquemment négligé. Elle expose l'intégralité du schéma — types, champs, relations — et constitue une carte détaillée pour l'attaquant. La désactiver en production est une mesure simple à fort impact. Les alias floodingpermettent d'envoyer des milliers d'opérations dans une seule requête en les aliasant différemment, contournant les limitations naïves par comptage de requêtes.
Sécurité spécifique à GraphQL
GraphQL présente une surface d'attaque distincte qui nécessite une approche dédiée, documentée dans l'OWASP GraphQL Security Cheat Sheet. La flexibilité qui fait sa force — les clients choisissent exactement les données qu'ils veulent — est aussi sa principale faiblesse de sécurité si aucune garde-fou n'est en place.
Les batching attacksexploitent la capacité de GraphQL à exécuter plusieurs opérations dans une même requête HTTP. Un attaquant peut envoyer des milliers de mutations d'authentification dans un seul appel, contournant un rate limiting qui compte les requêtes HTTP. La mitigation passe par une limitation du nombre d'opérations par batch et par un rate limiting basé sur le contenu plutôt que sur la requête HTTP.
L'autorisation au niveau des resolvers est l'erreur architecturale la plus critique. Sécuriser uniquement la route HTTP (POST /graphql) est insuffisant : si la route est accessible, tous les resolvers le sont. L'autorisation doit être vérifiée dans chaque resolver, pour chaque champ sensible. Des bibliothèques comme graphql-shieldpermettent de définir des règles d'autorisation déclaratives, appliquées automatiquement à chaque resolver selon des règles granulaires, jusqu'au niveau du champ individuel. Cette approche garantit que la logique d'autorisation est centralisée, testable et exhaustive.
Les persisted queriesconstituent l'approche la plus robuste pour les APIs GraphQL en production. Le client envoie un hash identifiant une requête pré-enregistrée côté serveur plutôt que la requête complète. Ce mécanisme élimine les attaques par complexité, les injections via les arguments de requête et l'abus de l'introspection, tout en réduisant la bande passante.
API Gateway et observabilité de sécurité
Une API gateway centralise les préoccupations transverses de sécurité : authentification, rate limiting, logging, transformation de requêtes, routage. Des solutions comme Kong, AWS API Gateway ou Traefikavec des middlewares de sécurité offrent une couche de protection uniforme devant l'ensemble des services backend. Cette centralisation évite la réimplémentation de logiques de sécurité dans chaque service, réduit les écarts de configuration et facilite les audits.
La corrélation des logs est indispensable à la détection d'incidents. Chaque requête doit porter un identifiant de corrélation (X-Correlation-ID ou X-Request-ID) propagé à travers tous les services impliqués. Les logs structurés (JSON) permettent une agrégation et une analyse efficaces dans des systèmes comme Elasticsearch, Loki ou CloudWatch. Sans corrélation, reconstituire la chronologie d'une attaque dans une architecture microservices est un exercice quasi impossible.
La détection d'anomaliesrepose sur l'établissement d'une baseline du trafic normal. Un volume inhabituel de requêtes 404 peut signaler une tentative d'énumération d'endpoints. Une multiplication des erreurs 401/403 sur un endpoint d'authentification indique du credential stuffing. De nouveaux patterns d'accès depuis des plages IP inconnues méritent une investigation. Les alertes sur les taux d'erreur 4xx et 5xx inhabituels doivent être configurées avec des seuils adaptés aux patterns de trafic de chaque API.
OWASP API Security Top 10 : les risques à connaître
L'OWASP API Security Top 10 identifie les risques les plus fréquents et les plus impactants. En voici les cinq plus critiques, avec un exemple d'exploitation et la contre-mesure correspondante.
BOLA — Broken Object Level Authorization. C'est le risque numéro un. L'API expose un endpoint GET /orders/1234sans vérifier que l'utilisateur authentifié est propriétaire de la commande 1234. Un attaquant incrémente simplement l'identifiant pour accéder aux commandes d'autres clients. La contre-mesure est systématique : pour chaque accès à une ressource, vérifier que l'identité authentifiée a le droit d'accéder à cette ressource spécifique, et non juste à la collection.
Broken Authentication. Tokens sans expiration, secrets JWT trop faibles, absence de limite de tentatives sur les endpoints d'authentification — chacune de ces lacunes ouvre une porte. Exemple : un token JWT signé avec HS256et une clé de 8 caractères peut être bruteforcé en quelques minutes. La contre-mesure : clés longues (256 bits minimum), rotation régulière, limitation stricte des tentatives, détection des patterns d'authentification anormaux.
Excessive Data Exposure.L'API renvoie l'objet complet issu de la base de données et délègue le filtrage au client. Si le client ne demande pas un champ, il n'est pas affiché — mais il est transmis dans la réponse HTTP. Un attaquant interceptant le trafic accède à tous les champs. La contre-mesure : ne jamais sérialiser plus que ce qui est nécessaire, utiliser des DTOs (Data Transfer Objects) ou des projections explicites.
Lack of Resources & Rate Limiting.Sans limitation, un endpoint de génération de rapport PDF peut être appelé en boucle, épuisant les ressources serveur. Ou un endpoint d'envoi d'email peut être utilisé pour du spam en masse. La contre-mesure : rate limiting à plusieurs niveaux (IP, token, endpoint), timeouts sur les opérations longues, pagination obligatoire sur les endpoints de liste.
Security Misconfiguration. CORS trop permissif (Access-Control-Allow-Origin: *sur une API authentifiée), en-têtes de sécurité absents, TLS 1.0 accepté, introspection GraphQL activée en production, stack trace exposée dans les messages d'erreur — les mauvaises configurations sont légion. La contre-mesure : une revue de configuration systématique, des tests automatisés de configuration de sécurité dans le pipeline CI, et un principe de refus par défaut.
La sécurité d'une API n'est pas une fonctionnalité qu'on ajoute après coup : c'est une propriété qui se conçoit dès l'architecture et qui se vérifie à chaque pull request.
La sécurisation des APIs REST et GraphQL est un effort continu, pas un état final. Les vecteurs d'attaque évoluent, les architectures changent, et de nouveaux endpoints sont exposés à chaque release. Une checklist minimale pour chaque API mise en production : authentification vérifiée et testée, autorisation au niveau objet (BOLA), rate limiting configuré, validation stricte des entrées, introspection GraphQL désactivée si applicable, logs de sécurité activés et corrélés, revue OWASP API Top 10 effectuée, tests de sécurité automatisés dans le pipeline CI.