Liste de contrôle pour les tests de sécurité des API REST

Les tests de sécurité des API REST consistent à prouver qu’un utilisateur connecté ne peut pas atteindre ce qui ne lui appartient pas. Ils comptent parce que la plupart des attaques arrivent depuis exactement cette position plutôt que par effraction. Votre écran de connexion peut être irréprochable pendant que l’endpoint situé derrière remet à un client payant la facture de quelqu’un d’autre.

Trouver ce genre de faille ne demande rien de spécialisé, seulement deux comptes ordinaires et un outil capable d’envoyer des requêtes. Le plus dur est de répéter ce travail avant chaque version, sans jamais sauter un tour. Beaucoup d’équipes y parviennent quelques mois puis arrêtent en silence, et c’est pourquoi un partenaire QA dédié vaut la peine. Nos services de tests d’intrusion vont plus loin encore lorsque l’enjeu appelle un expert extérieur.

Comment tester l'authentification et l'autorisation sur chaque endpoint

L’authentification demande qui vous êtes. L’autorisation demande ce que vous avez le droit de faire une fois que le système le sait. Tous les utilisateurs rencontrent l’écran de connexion, alors la première est construite avec soin et fonctionne généralement. La seconde est vérifiée sur les endpoints auxquels quelqu’un a pensé, et omise sur ceux auxquels personne n’a pensé.

Salt Labs a suivi une année d’attaques réelles et a constaté que 95% provenaient de sources authentifiées, donc les appelants dont il faut se méfier ont déjà franchi la porte.

La liste de contrôle de sécurité des API REST commence ici, où chaque vérification a la même forme : envoyer une requête qui devrait être refusée, depuis un appelant qui n’a aucun droit de la formuler.

  • Appelez chaque endpoint sans aucune authentification. Tout ce qui répond par des données plutôt que par un refus est un constat.
  • Recommencez avec une authentification expirée, puis avec une qui appartient à un autre compte.
  • Connectez-vous en tant qu’utilisateur ordinaire et demandez un endpoint réservé aux administrateurs directement par son adresse, sans approcher l’interface.
  • Confirmez qu’une authentification cesse de fonctionner dès que quelqu’un se déconnecte ou qu’un administrateur désactive le compte.
  • Vérifiez le parcours de réinitialisation du mot de passe des deux côtés. Un lien qui reste valide après usage, ou qui peut être demandé pour une adresse qui n’est pas la vôtre, annule tout le reste de cette liste.

Le principe à retenir est qu’une API correcte refuse. Elle ne renvoie ni liste vide, ni enregistrement partiel, ni message aimable expliquant ce que vous avez failli obtenir. Ces quasi-succès indiquent à un attaquant que l’adresse était réelle et méritait un autre essai.

Vulnérabilité BOLA : quand un identifiant renvoie les données de quelqu'un d'autre

Voici la vulnérabilité d’API REST la plus répandue, et elle porte un nom disgracieux : autorisation au niveau objet défaillante, généralement abrégée en BOLA.

L’idée est plus simple que le terme. Les adresses web d’une API REST nomment souvent l’enregistrement demandé, si bien qu’une facture peut se trouver à /invoices/8812. Une vulnérabilité BOLA existe quand un client connecté remplace ce numéro par 8813 et lit le relevé d’une autre entreprise. La connexion a fonctionné exactement comme prévu. Ce qui n’est jamais arrivé, c’est une deuxième vérification, celle qui demande si ce client possédait cet enregistrement.

BOLA est la version API d’un problème plus large, que nous traitons dans notre article sur le contrôle d’accès défectueux. Salt Labs le compte aux côtés des failles d’injection, où un attaquant cache une commande dans un champ de formulaire ordinaire. À eux deux, ils représentaient 37% de tous les problèmes signalés, la plus grosse part isolée.

Tester BOLA est sans éclat et rapide :

  • Créez deux comptes ordinaires. Connectez-vous avec le premier et notez les identifiants qui vous appartiennent légitimement.
  • Demandez les identifiants du second compte tout en restant connecté au premier. Faites-le pour la lecture, la mise à jour et la suppression, car beaucoup d’API protègent l’une de ces actions et oublient les autres.
  • Essayez des identifiants qui n’appartiennent à personne, et d’autres issus d’une plage voisine. Une réponse qui distingue “pas à vous” de “n’existe pas” révèle quels enregistrements sont réels.
  • Recommencez sur chaque endpoint qui accepte un identifiant, y compris les rapports, les exports et les pièces jointes. On les oublie parce qu’ils ressemblent à des fonctionnalités plutôt qu’à des données.
  • Vérifiez aussi les adresses imbriquées. Protéger /orders/88 sert peu si /orders/88/items répond à tout le monde.

Automatiser ces vérifications se rentabilise, puisque les deux mêmes comptes peuvent alimenter des centaines de requêtes appariées à chaque version. Écrire et maintenir ces tests, c’est le travail de notre équipe de tests automatisés.

Comment tester la limitation de débit sur une API REST

Une limite de débit est un plafond sur la fréquence à laquelle un seul appelant peut demander. Sans elle, un simple script peut deviner des mots de passe toute la nuit, épuiser un service payant que vous revendez, ou simplement saturer le serveur pour tout le monde.

Quand un appelant dépasse le plafond, la bonne réponse est le code de statut 429, qui signifie “trop de requêtes”. Les mauvaises réponses sont une page lente, un délai dépassé, ou une erreur 500 qui signale un plantage au lieu d’un refus délibéré.

Les vérifications qui suivent poussent toutes l’API au-delà de sa limite, exécutez-les donc sur un environnement de test plutôt qu’en production.

  • Envoyez une rafale de requêtes bien au-delà de ce que produirait un vrai client, puis confirmez que vous obtenez des réponses 429 plutôt que du silence.
  • Vérifiez que la limite s’applique par compte et par adresse, pas seulement globalement. Un plafond uniquement global laisse un appelant abusif dégrader le service de tous.
  • Martelez précisément les parcours de connexion et de réinitialisation du mot de passe. Ils méritent des limites plus strictes que le reste, car c’est là que deviner rapporte.
  • Examinez à part les endpoints coûteux. Une recherche ou un rapport qui consomme une seconde de serveur demande un plafond plus bas qu’un appel qui renvoie un nom.
  • Confirmez que la limite se réinitialise sensément et indique à l’appelant quand réessayer, pour que les clients légitimes lèvent le pied au lieu de boucler.

Les limites de débit vous protègent aussi de vos propres clients. Leur logiciel peut continuer d’envoyer la même requête échouée sans la moindre pause. Du côté de votre serveur, cela ressemble exactement à une attaque.

Validation des entrées : ce que votre API fait d'une requête incorrecte

Chaque champ que votre API accepte est un endroit où quelqu’un peut placer une valeur que vous n’attendiez pas. Les tests fonctionnels couvrent les valeurs que votre propre application enverrait, c’est-à-dire l’essentiel de ce qu’un vrai client produit un jour. Cependant, personne ne saisit un nom de plusieurs milliers de caractères, ne commande moins cinq unités de quelque chose, ni ne choisit une date de livraison en l’an 3000, votre API ne les voit donc jamais en usage normal.

Tôt ou tard, quelqu’un les envoie quand même, soit un attaquant qui sonde, soit un logiciel qui déraille. Le dommage est rarement spectaculaire. Le plus souvent, l’API enregistre l’absurdité et quelque chose ailleurs dans le système casse des semaines plus tard, ou bien elle renvoie une erreur si détaillée qu’elle nomme votre base de données et sa version.

Pour tester cela, alimentez l’endpoint avec des valeurs qu’il ne devrait jamais accepter, puis observez sa réaction.

  • Envoyez le mauvais type dans chaque champ : du texte là où va un nombre, un nombre là où va une date, rien du tout là où quelque chose est exigé.
  • Envoyez des valeurs très en dehors de la plage raisonnable, y compris des négatifs, zéro, et des longueurs qui atteignent les mégaoctets.
  • Envoyez des champs que l’endpoint n’a jamais documentés. Une mise à jour qui accepte discrètement is_admin ou credit_limit permet à un client de se promouvoir lui-même, et elle mérite un coup d’oeil sur chaque endpoint qui enregistre des données.
  • Envoyez des caractères qui signifient quelque chose pour une base de données ou une ligne de commande. L’injection fonctionne exactement ainsi, confirmez donc qu’ils reviennent en texte brut plutôt qu’en instructions.
  • Lisez les messages d’erreur. Un refus devrait dire que la requête était incorrecte, pas nommer la bibliothèque qui l’a rejetée ni la table sur laquelle elle a échoué.

La faille que vous traquez est une API qui fait confiance à son propre front end. Si votre propre application n’envoie jamais de valeur incorrecte, on n’a peut-être jamais demandé à l’endpoint situé derrière de dire non.

CORS, JWT et sur-partage : trois façons dont les API REST laissent fuir des données

Trois choses expliquent l’essentiel des expositions accidentelles, et aucune ne suppose qu’un attaquant casse quoi que ce soit.

CORS signifie partage des ressources entre origines. Un navigateur empêche normalement un site web de lire des données qui appartiennent à un autre, et CORS est la façon dont votre API accorde une exception. Réglé pour accepter tout le monde, il invite n’importe quelle page d’internet à formuler des requêtes en utilisant la session d’un visiteur. Confirmez que la liste autorisée ne nomme que vos domaines réels, que les identifiants ne sont permis que pour ceux-là, et que personne n’a laissé une règle ouverte après un débogage.

JWT signifie jeton web JSON. Il fonctionne comme un laissez-passer : votre API en remet un après la connexion, et l’application l’envoie avec chaque requête suivante. Une signature prouve que le jeton est authentique et intact, votre serveur n’a donc jamais à redemander le mot de passe. Ce raccourci ajoute quatre points à votre liste :

  • Confirmez que les jetons expirent, et qu’un ancien est réellement rejeté plutôt qu’accepté avec un avertissement.
  • Vérifiez que la signature est contrôlée. Une API qui accepte un jeton déclarant n’en avoir aucune est une défaillance connue et grave.
  • Regardez ce que le jeton transporte. Quiconque le détient peut en lire le contenu, donc une adresse e-mail convient et un mot de passe ou une note interne non.
  • Assurez-vous que la déconnexion, ou la révocation d’un accès par un administrateur, met fin à la session avant que le jeton n’expire naturellement.

Le sur-partage désigne une réponse qui transporte plus de données que l’écran n’en affiche jamais. Un client voit son nom et le total de sa commande, tandis que la réponse derrière contient aussi une note de solvabilité, le prix de revient d’un fournisseur, ou l’adresse e-mail d’un autre client. Rien de cela n’apparaît à l’écran, et tout cela a pourtant atteint le navigateur. Salt Labs situe l’exposition de données sensibles à 34% des problèmes signalés, juste derrière les 37% des failles d’autorisation et d’injection. Lisez la réponse brute de chaque endpoint qui renvoie un enregistrement, et comparez-la à ce que cet utilisateur a le droit de voir.

Tests de sécurité des API REST sur un produit en production

Un projet client montre toute la liste à l’oeuvre. Union54 émet des cartes de paiement pour des entreprises fintech partout en Afrique. À notre arrivée, le produit n’avait aucun front end, donc chaque vérification s’exécutait directement contre les endpoints. C’est la position dans laquelle vous vous retrouvez chaque fois que l’interface traîne derrière le back end, ou n’est jamais construite. Notre pratique de tests d’API place les vérifications de sécurité dans la même passe que les fonctionnelles, au lieu de les remettre à plus tard.

Le travail manuel est passé par Postman, qui convient à une API où il n’y a rien à cliquer. L’automatisation a commencé sous Mocha et est passée à Cypress quand la suite a grossi et que la stabilité est devenue le problème. Ce basculement vaut mieux tôt que tard. À la fin, la couverture automatisée atteignait 90% des endpoints sur plus de 1 500 scénarios. La mission a fait remonter plus de 190 défauts, tous dans une fenêtre de deux mois fixée par la démonstration aux investisseurs du client.

L’un de ces défauts montre pourquoi lire les réponses compte. Une carte revenait en annonçant un solde de zéro et un statut émise, alors que la base de données derrière contenait un solde positif et un statut bloquée. Les deux réponses étaient bien formées et aucune ne paraissait cassée. Seule la comparaison de la réponse avec l’enregistrement sous-jacent a révélé qu’on racontait à l’appelant quelque chose de faux sur son propre argent.

Cette comparaison est l’habitude qu’enseigne cette liste. Le travail fonctionnel demande si une réponse arrive. Le travail de sécurité demande si elle aurait dû arriver.

Là où s'arrête la liste de contrôle de sécurité des API REST

Parcourez cette liste à chaque version et vous trouverez les problèmes coûteux tant qu’ils sont encore bon marché à corriger. Une suite fonctionnelle n’en signale aucun, car pour ce qu’elle en sait, chaque réponse est arrivée exactement comme prévu.

Trois activités sont mises dans le même sac sous le nom de “tests d’API”, et savoir laquelle vous achetez compte :

Activité
La question à laquelle elle répond
Qui la mène
Activité

Tests d’API

La question à laquelle elle répond

L’endpoint renvoie-t-il les bonnes données ?

Qui la mène

Vos propres testeurs, à chaque version

Activité

Tests de sécurité des API REST

La question à laquelle elle répond

Un utilisateur connecté peut-il atteindre ce qui ne lui appartient pas ?

Qui la mène

Les mêmes testeurs, la même version

Activité

Tests d’intrusion d’API

La question à laquelle elle répond

Que pourrait obtenir un attaquant déterminé ?

Qui la mène

Des spécialistes extérieurs, en mission cadrée

La ligne du milieu est ce que vous venez de parcourir. Notre liste de contrôle pour tester les API REST couvre la première. Les deux vont bien ensemble, puisque beaucoup de vérifications de sécurité sont un test fonctionnel qui marche, avec le résultat attendu inversé.

REST n’est pas la seule façon de construire une API. Pour les mêmes problèmes sur GraphQL, gRPC et SOAP, notre guide des tests de sécurité des API parcourt l’OWASP API Top 10, le classement de référence du secteur pour les risques liés aux API.

Acheter la troisième ligne est une décision à part. Ce type de mission convient à une grande version, à une entrée sur un marché réglementé, ou à un acheteur grand compte qui veut des preuves avant de signer. Elle rapporte davantage une fois que vos propres équipes ont écarté les constats faciles, car payer un expert pour les redécouvrir est de l’argent perdu.

Curieux de savoir ce que vos endpoints livrent à un appelant connecté qui va fouiller ? Réservez une revue avec notre équipe QA.

FAQ

Qu'est-ce que les tests de sécurité des API REST ?

Les tests de sécurité des API REST demandent comment un utilisateur connecté pourrait abuser d’une API REST plutôt que simplement s’en servir. Ils couvrent l’application des permissions sur chaque endpoint, la question de savoir si un client peut atteindre les enregistrements d’un autre, les plafonds de requêtes, la gestion des jetons, et ce que les réponses laissent filtrer. Les tests fonctionnels prouvent que l’API marche. Un test d’intrusion est une mission spécialisée, cadrée et distincte.

Qu'est-ce qu'une vulnérabilité BOLA ?

BOLA signifie autorisation au niveau objet défaillante. Cela se produit quand un utilisateur connecté demande un enregistrement qui n’est pas le sien, souvent un rapport ou une pièce jointe dont l’adresse contient un identifiant, et que l’API le lui remet quand même. La connexion réussit, et la question de la propriété n’est tout simplement jamais posée. C’est la faille la plus répandue des API REST et la plus facile à tester.

En quoi les tests de sécurité des API REST diffèrent-ils des tests d'intrusion ?

La différence tient à qui paie et à quelle fréquence cela arrive. Les tests de sécurité sont un travail que votre équipe fait déjà, ils tournent donc à chaque version. Les tests d’intrusion sont une mission cadrée que vous achetez : des spécialistes extérieurs attaquent délibérément le système, cela arrive donc beaucoup plus rarement. Écarter d’abord vos propres constats garde ce budget braqué sur des problèmes que votre équipe n’aurait jamais pu trouver.

À quelle fréquence faut-il dérouler une liste de contrôle de sécurité des API REST ?

Répétez les vérifications de permissions et d’entrées à chaque version, car une petite modification sur un rôle peut discrètement élargir qui voit quoi. Programmez une passe plus approfondie chaque fois que vous publiez de nouveaux endpoints, changez le fonctionnement des sessions, ou branchez un prestataire extérieur. Gardez une mission spécialisée complète pour un grand lancement, une refonte majeure, ou une échéance de conformité.

Peut-on tester la sécurité d'une API REST sans accès au code source ?

Oui, et l’essentiel de cette liste part du principe que vous ne voyez pas le code. Chaque vérification ici s’exécute de l’extérieur, avec des comptes ordinaires et un outil capable d’envoyer des requêtes. Cela reproduit exactement la position d’un attaquant, puisqu’il n’a pas non plus votre code source. Lire le code aide sur certains problèmes, même si ce n’est pas nécessaire pour trouver les plus courants.

Découvrez un échantillon de notre revue de code de sécurité d'une plateforme e-commerce basée aux États-Unis

Ce rapport met en avant les exploits que nous avons trouvés, catégorisés par gravité, avec des recommandations pour les corriger.
Veuillez saisir votre adresse courriel professionnelle n'est pas un courriel professionnel