API : développement sécurisé et intégrations modernes

·

Une API sécurisée combine OAuth 2.0 et PKCE, des jetons de courte durée de vie, une validation stricte par schéma et le rate limiting, car selon l'OWASP API Security Top 10, les failles les plus exploitées sont des erreurs d'autorisation (BOLA) et de logique métier, pas des faiblesses de chiffrement.

Code source sur l'écran d'un ordinateur

Les API (interfaces de programmation d'applications) sont le tissu conjonctif du logiciel actuel : chaque paiement par carte, chaque connexion avec un compte externe et chaque intégration entre systèmes passe par une API. Cette centralité en fait aussi le principal vecteur d'attaque. Selon l'OWASP API Security Top 10, les vulnérabilités les plus exploitées ne sont pas des failles exotiques, mais des erreurs de conception dans l'autorisation et la validation. Développer une API sécurisée, ce n'est pas ajouter une couche à la fin, mais prendre les bonnes décisions d'architecture, d'authentification et de contrôle d'accès dès le premier endpoint.

REST et GraphQL : quand utiliser chacun

Le choix du style architectural conditionne le modèle de sécurité. REST organise l'API en ressources identifiées par URL et méthodes HTTP (GET, POST, PUT, DELETE), avec une surface d'attaque prévisible : chaque endpoint protège une ressource. GraphQL expose un unique endpoint sur lequel le client compose des requêtes flexibles, ce qui réduit le sur-envoi de données mais introduit des risques propres, comme des requêtes imbriquées pouvant provoquer un déni de service si leur profondeur et leur complexité ne sont pas limitées.

AspectRESTGraphQL
EndpointsMultiples, un par ressourceUn seul
Récupération des donnéesRisque de over/under-fetchingLe client demande exactement ce dont il a besoin
Cache HTTPNative et simpleComplexe (tout est en POST)
Risque caractéristiqueEndpoints exposés sans autorisationRequêtes profondes et coûteuses

Authentification et autorisation : ce n'est pas la même chose

Confondre ces deux concepts est à l'origine de nombreuses failles. L'authentification répond à « qui êtes-vous ? » et l'autorisation à « que pouvez-vous faire ? ». La norme de référence pour déléguer l'accès est OAuth 2.0 (RFC 6749), qui permet à une application d'accéder à des ressources au nom de l'utilisateur sans manipuler son mot de passe, au moyen de jetons d'accès. OpenID Connect s'appuie sur OAuth 2.0 en ajoutant la couche d'identité (savoir qui est l'utilisateur, pas seulement ce qu'il peut faire).

Pour le flux des applications serveur, on utilise l'Authorization Code Flow, et pour les applications publiques (SPA et mobile), on y ajoute PKCE (Proof Key for Code Exchange, RFC 7636), qui empêche l'interception du code d'autorisation. Les jetons prennent généralement la forme de JWT (JSON Web Tokens) : des jetons signés que le serveur peut valider sans interroger une base de données. Il est recommandé de garder les access tokens à courte durée de vie et de déléguer le renouvellement à des refresh tokens à durée de vie plus longue et révocables.

BOLA : la vulnérabilité numéro un

La première place de l'OWASP API Security Top 10 est occupée par BOLA (Broken Object Level Authorization). Cela se produit lorsqu'un endpoint vérifie que l'utilisateur est authentifié, mais pas que l'objet demandé lui appartient. L'exemple classique : GET /api/facturas/1043 renvoie correctement la facture à l'utilisateur propriétaire, mais si un autre utilisateur authentifié change l'identifiant en 1044 et reçoit la facture d'un tiers, l'API présente une vulnérabilité BOLA grave. La défense consiste à toujours vérifier, à chaque opération, que le sujet authentifié a la permission sur l'objet concerné, sans jamais se fier au fait qu'un identifiant difficile à deviner suffise comme protection.

Rate limiting et protection contre les abus

Sans limitation de débit, une API est exposée à la force brute sur les identifiants, au scraping massif et au déni de service. Le rate limiting restreint le nombre de requêtes par client sur une fenêtre temporelle. Les algorithmes les plus utilisés sont le token bucket (autorise des rafales contrôlées), le leaky bucket (lisse le débit) et la fenêtre glissante (sliding window). Il est recommandé de communiquer les limites via des en-têtes standards comme RateLimit-Limit et RateLimit-Remaining, et de répondre avec le code 429 Too Many Requests accompagné de l'en-tête Retry-After lorsque le seuil est dépassé.

Validation des entrées et prévention des injections

Toute entrée du client est hostile jusqu'à preuve du contraire. La validation doit appliquer le principe de liste blanche : définir explicitement ce qui est accepté (type, longueur, format, plage) et rejeter le reste, plutôt que d'essayer de filtrer le mauvais. Les requêtes vers la base de données doivent toujours utiliser des requêtes paramétrées pour neutraliser l'injection SQL, et la sortie doit être encodée selon le contexte pour prévenir les XSS. Valider un schéma de requête avec des outils comme JSON Schema ou la spécification OpenAPI permet de rejeter les requêtes malformées avant qu'elles n'atteignent la logique métier.

L'API gateway : un point de contrôle unique

À mesure que le nombre de services augmente, gérer la sécurité endpoint par endpoint devient ingérable. L'API gateway résout ce problème en se plaçant devant les services comme point d'entrée unique. Il centralise des tâches transversales qu'il faudrait sinon réimplémenter dans chaque service : terminaison TLS, validation des jetons, application du rate limiting et des quotas, routage, transformation des requêtes et journalisation du trafic. Concentrer ces fonctions dans le gateway évite la duplication de la logique de sécurité et, surtout, évite les incohérences : un seul endroit où l'on décide qui peut appeler et à quelle fréquence.

Le gateway est aussi l'endroit naturel pour implanter le modèle de confiance zéro dans les communications internes. Dans les architectures de microservices modernes, les services s'authentifient entre eux via mTLS (TLS mutuel), de sorte que chaque appel interne vérifie à la fois l'identité du client et celle du serveur. Ainsi, compromettre un seul service ne donne pas un accès libre au reste du système, car chaque saut exige toujours des identifiants valides.

Sécurité des webhooks

Les webhooks inversent le flux habituel : au lieu que le client interroge l'API, c'est le serveur qui notifie le client lorsqu'un événement se produit. Cela pose un risque différent, car le récepteur expose un endpoint public que n'importe qui pourrait invoquer. La défense standard est la vérification de signature : l'émetteur calcule un HMAC du corps du message avec un secret partagé et l'envoie dans un en-tête ; le récepteur recalcule la signature et la compare avant de traiter quoi que ce soit. Il est également recommandé d'inclure un horodatage dans la signature pour éviter les attaques par rejeu (replay) et rejeter les messages anciens.

Étapes pour concevoir une API sécurisée

  1. Forcer HTTPS sur tous les endpoints ; ne jamais accepter de trafic en clair.
  2. Authentifier avec OAuth 2.0 / OpenID Connect et des jetons de courte durée de vie, en évitant les clés API statiques intégrées dans les clients.
  3. Autoriser au niveau de l'objet et de la fonction à chaque requête, en appliquant le modèle du moindre privilège.
  4. Valider toutes les entrées par rapport à un schéma et paramétrer les requêtes.
  5. Appliquer le rate limiting et des quotas par client, utilisateur et IP.
  6. Versionner l'API (/v1/, /v2/) pour évoluer sans casser les intégrations.
  7. Journaliser et surveiller les accès et les anomalies, sans déverser de données sensibles dans les logs.
  8. Documenter avec OpenAPI et maintenir la documentation synchronisée avec le code.

Erreurs courantes

La première est l'autorisation rompue au niveau de l'objet (BOLA) déjà décrite. La deuxième est l'exposition excessive de données : renvoyer l'objet complet de la base de données en comptant sur le client pour n'afficher que les champs pertinents, alors que l'attaquant inspecte la réponse brute. La troisième est le manque de limitation des ressources, laissant l'API ouverte à des paginations massives ou à des requêtes GraphQL illimitées. La quatrième est la mauvaise gestion des secrets : clés et jetons dans le code source ou dans les dépôts. La cinquième, et très fréquente, est l'API shadow ou zombie : des endpoints de versions anciennes qui restent actifs sans maintenance ni protection.

Questions fréquentes

Qu'est-ce qui est préférable, une clé API ou OAuth 2.0 ? Les clés API identifient une application mais pas un utilisateur, et sont difficiles à faire tourner et à révoquer. OAuth 2.0 offre des jetons de courte durée de vie, des périmètres de permission (scopes) et la révocation. Pour l'accès utilisateur, OAuth 2.0 avec OpenID Connect est la norme recommandée ; les clés API restent réservées aux intégrations serveur à serveur à faible risque.

GraphQL est-il moins sûr que REST ? Il n'est pas moins sûr par nature, mais il déplace le risque : dans REST, on surveille chaque endpoint ; dans GraphQL, il faut limiter la profondeur et la complexité des requêtes, appliquer des listes blanches d'opérations et désactiver l'introspection en production.

Où stocker les jetons dans une application web ? Pour les SPA, éviter localStorage en raison de son exposition aux XSS ; préférer des cookies HttpOnly, Secure et SameSite, complétés par une protection CSRF. Pour le mobile, utiliser le stockage sécurisé du système d'exploitation.

À quelle fréquence dois-je faire tourner les identifiants ? Les access tokens doivent expirer en minutes ou en heures ; les secrets client et les clés API doivent être renouvelés périodiquement et, impérativement, en cas de suspicion de fuite, avec un processus de rotation automatisé et sans interruption.

Conclusion

La sécurité d'une API se gagne ou se perd dans la conception de l'autorisation, pas dans la puissance du chiffrement. Le constat le plus révélateur de l'OWASP API Security Top 10 est que les failles dominantes (BOLA, autorisation rompue au niveau de la fonction, exposition excessive de données) sont des erreurs de logique métier qu'aucun outil automatique ne détecte totalement : elles dépendent de la vérification, à chaque opération, que cet utilisateur peut faire ceci sur cet objet. Une API moderne combine OAuth 2.0 avec PKCE, des jetons de courte durée de vie, une validation stricte par schéma, du rate limiting et de l'observabilité, le tout versionné et documenté avec OpenAPI. Chez Summum, nous concevons et intégrons des API en appliquant ce modèle dès le premier endpoint, de sorte qu'ouvrir une intégration à un tiers ne signifie pas ouvrir une porte au reste du système.