Sécuriser vos API à la périphérie : REST, GraphQL et l'abus automatisé
Une API n’est pas une page web — et vos défenses le savent-elles ?
La plupart des équipes protègent soigneusement leur interface web, puis exposent une API qui parle le même langage HTTP mais suit des règles très différentes. Pas de formulaire à remplir, pas de navigateur à défier avec un CAPTCHA, souvent pas de session : juste un jeton, un point de terminaison et un client qui peut être n’importe quoi. C’est précisément ce qui en fait la cible préférée de l’abus automatisé — énumération d’objets, bourrage d’identifiants, extraction massive de données.
Protéger une API à la périphérie, c’est appliquer le filtrage avant que la requête n’atteigne votre origine, sans dépendre du fait que chaque équipe backend ait pensé à toutes les défenses. C’est une couche de contrôle uniforme là où le trafic entre, quelle que soit la maturité du service derrière.
REST : l’abus se cache dans le volume et la forme
Les attaques contre une API REST ressemblent rarement à une injection classique. Elles ressemblent à un usage presque normal :
- Énumération. Un client parcourt
/orders/1,/orders/2,/orders/3… en incrémentant un identifiant. Chaque requête est valide isolément ; c’est la séquence qui est un vol de données. - Extraction de masse. Un point de terminaison de recherche conçu pour dix résultats est appelé dix mille fois avec des filtres différents pour reconstituer toute la base.
- Charges malformées. Un corps JSON surdimensionné, une profondeur d’imbrication absurde, un type inattendu — de quoi faire tomber un parseur naïf.
À l’edge, nos deux moteurs WAF à signatures — un dans un bac à sable WASM, un natif — appliquent le jeu de règles OWASP sur le corps comme sur l’URL, tandis que la limitation de débit et le scoring d’entité repèrent la séquence abusive qu’aucune requête isolée ne trahit. Le rythme, l’origine et la forme sont corrélés dans le temps, pas jugés un appel à la fois.
GraphQL : un seul point de terminaison, mille façons d’abuser
GraphQL déplace la complexité côté client : une seule URL, mais une requête arbitrairement profonde. Un attaquant peut demander un graphe d’objets imbriqués qui force votre backend à des milliers de résolutions pour une seule requête HTTP — un déni de service par la seule structure de la demande.
La défense n’est pas de bloquer GraphQL, mais de traiter la forme de la requête comme une donnée à contrôler : rejeter une profondeur d’imbrication déraisonnable, plafonner le coût, et surtout appliquer une limitation de débit qui compte le travail réel, pas seulement le nombre d’appels. Un seul appel GraphQL coûteux peut peser plus qu’une centaine de requêtes REST triviales.
Le jeton n’est pas une identité — c’est un secret volable
Beaucoup d’API considèrent qu’un jeton valide égale un client de confiance. Mais un jeton fuite : dans un dépôt public, un log, une extension de navigateur. Une fois volé, il ouvre la porte comme un badge d’accès copié.
C’est pourquoi le filtrage périphérique ne s’arrête pas à « le jeton est-il valide ». Il regarde le comportement derrière le jeton : un identifiant légitime soudain utilisé depuis une nouvelle géographie, à un rythme industriel, sur des points de terminaison qu’il ne touchait jamais, est un signal — même si la signature du jeton est parfaite. La limitation par identité et le scoring d’entité rendent un jeton volé beaucoup moins utile qu’un simple secret partagé. Notre article sur la limitation de débit contre le bourrage d’identifiants creuse ce point.
Souveraineté et traçabilité
Pour une API qui traite des données personnelles, la question n’est pas seulement « est-ce bloqué », mais « où passe la donnée et qui peut la lire ». Nos nœuds tournent dans l’UE (Hetzner, OVH, Scaleway) : c’est un choix d’architecture, pas une option. Chaque décision de filtrage est consignée dans un journal d’audit immuable, en ajout seul, ce qui vous donne la piste vérifiable qu’exige le RGPD en cas d’incident. Voyez comment ça fonctionne de bout en bout.
Ce que nous ne prétendons pas
Un WAF à la périphérie ne remplace ni l’authentification, ni l’autorisation, ni la validation dans votre code. Un contrôle d’accès cassé côté serveur reste cassé, quelles que soient les défenses en amont. Notre rôle est d’ajouter une couche uniforme qui absorbe l’abus automatisé et vous donne la visibilité — pas de vous dispenser d’écrire une API correcte. Et côté performance, le filtrage tient dans un budget de conception de ≤5 ms, mesuré en staging, jamais présenté comme un benchmark de production.
Vous voulez voir comment vos API se comportent sous notre filtrage ? Donnez-nous votre domaine.