💡 Key Takeaways
- Authentication and Authorization: The Foundation That Everyone Rushes Past
- Request Validation: Where Most Bugs Actually Live
- Response Validation: Trust, But Verify
- State Management and Idempotency: The Subtle Art of Consistency
Il y a trois ans, j'ai vu une API de production échouer de manière spectaculaire à 2 heures du matin parce que personne n'avait testé ce qui se passe quand vous envoyez un champ de date formaté comme "32/13/2021". La cascade était belle dans le pire sens possible : 47 000 transactions échouées, des clients en colère inondant les canaux de support, et un PDG qui voulait des réponses que je n'avais pas. Cette nuit-là a changé ma façon d'aborder les tests d'API pour toujours.
💡 Points Clés
- Authentification et Autorisation : La Fondation Que Tout Le Monde Ignore
- Validation des Requêtes : Là Où Se Cachent La Majorité Des Bugs
- Validation des Réponses : Faites Confiance, Mais Vérifiez
- Gestion de l'État et Idempotence : L'Art Subtil de la Cohérence
Je suis Sarah Chen, et je suis ingénieure en automatisation QA depuis huit ans, dont les cinq dernières années se concentrent exclusivement sur les tests d'API pour les plateformes fintech et de santé. J'ai testé tout, des simples points de terminaison CRUD aux API de traitement de paiement complexes gérant des millions de dollars quotidiennement. Ce que j'ai appris est ceci : la plupart des échecs d'API ne sont pas des cas limites exotiques - ce sont des problèmes prévisibles qu'une liste de vérification systématique aurait attrapés.
La liste de vérification que je partage aujourd'hui est exactement celle que j'utilise pour chaque point de terminaison que je teste. Elle a sauvé mon équipe d'au moins une douzaine d'incidents en production au cours de la dernière année seule, et elle nous a aidés à maintenir un temps de disponibilité de 99,97 % sur plus de 230 points de terminaison d'API. Ce n'est pas de la théorie - c'est la réalité éprouvée de quelqu'un qui a été appelé à 3 heures du matin plus de fois que je ne veux m'en souvenir.
Authentification et Autorisation : La Fondation Que Tout Le Monde Ignore
Voici une statistique qui devrait vous terrifier : dans mon expérience d'audit des API à travers sept entreprises différentes, environ 60 % avaient au moins un point de terminaison avec une logique d'autorisation cassée. Pas d'authentification - d'autorisation. Le point de terminaison vérifiait que vous étiez connecté, mais ne vérifiait pas correctement si vous deviez accéder à cette ressource spécifique.
Ma liste de vérification d'authentification et d'autorisation commence par les bases évidentes mais souvent négligées :
- Tester sans aucun jeton d'authentification - doit renvoyer 401
- Tester avec un jeton expiré - doit renvoyer 401, pas 500
- Tester avec un jeton mal formé - doit renvoyer 401, pas planter
- Tester avec un jeton valide mais de mauvaises permissions - doit renvoyer 403
- Tester avec un jeton pour un autre utilisateur essayant d'accéder aux ressources d'un autre utilisateur
C'est ce dernier point où les choses deviennent intéressantes. Une fois, j'ai trouvé un point de terminaison où vous pouviez récupérer l'historique des paiements de n'importe quel utilisateur simplement en modifiant l'ID utilisateur dans l'URL, même si vous étiez authentifié en tant qu'un autre utilisateur. Le point de terminaison vérifiait si vous étiez connecté, mais n'a jamais vérifié si l'ID utilisateur demandé correspondait à votre ID utilisateur authentifié. Cela s'appelle une Référence d'Objet Direct Insecure (IDOR), et c'est étonnamment commun.
Je teste également explicitement les flux de rafraîchissement de jeton. Que se passe-t-il lorsqu'un jeton expire en cours de requête ? Votre API gère-t-elle cela gracieusement, ou laisse-t-elle le client dans un état étrange ? J'ai vu des systèmes où un jeton expiré pendant une requête POST renvoyait un 401, mais les données étaient encore partiellement écrites dans la base de données. C'est un cauchemar pour la cohérence des données.
Pour les API utilisant des clés API au lieu de jetons, je vérifie que la rotation des clés fonctionne correctement. Pouvez-vous générer une nouvelle clé ? L'ancienne clé cesse-t-elle immédiatement de fonctionner, ou y a-t-il une période de grâce ? Cette période de grâce est-elle documentée ? J'ai une fois travaillé avec une API où la rotation des clés avait une période de chevauchement de 24 heures que personne ne connaissait, entraînant des échecs d'audit de sécurité.
La matrice d'autorisation est mon arme secrète ici. Je crée une feuille de calcul avec chaque point de terminaison sur un axe et chaque rôle d'utilisateur sur l'autre. Ensuite, je teste systématiquement chaque combinaison. C'est ennuyeux, mais cela a permis de détecter des bugs d'autorisation dans 100 % des projets où je l'ai appliqué. Oui, 100 %. Ce n'est pas de l'exagération - chaque projet avait au moins un point de terminaison où la logique d'autorisation était incorrecte pour au moins un rôle.
Validation des Requêtes : Là Où Se Cachent La Majorité Des Bugs
Si je devais deviner où 70 % des bugs d'API proviennent, ce serait dans la validation des requêtes. Les développeurs sont des créatures optimistes - ils écrivent du code en supposant que les entrées seront raisonnables. Mais Internet n'est pas raisonnable, et les systèmes qui appellent vos API ne le sont pas non plus.
Ma liste de vérification de validation des requêtes est exhaustive parce qu'elle doit l'être :
- Envoyer un corps de requête complètement vide - que se passe-t-il ?
- Envoyer null pour chaque champ requis individuellement
- Envoyer des chaînes vides pour les champs de chaîne
- Envoyer des chaînes ne contenant que des espaces
- Envoyer des chaînes qui dépassent d'un caractère les limites de longueur
- Envoyer des chaînes qui sont 1000 fois trop longues
- Envoyer des nombres négatifs pour des champs s'attendant à des entiers positifs
- Envoyer zéro pour des champs où zéro pourrait être invalide
- Envoyer des nombres décimaux pour des champs entiers
- Envoyer des nombres extrêmement grands (test pour dépassement d'entier)
- Envoyer des nombres extrêmement petits (test pour sous-dépassement)
- Envoyer des caractères spéciaux dans les champs de chaîne : guillemets, barres obliques inverses, octets nuls, Unicode
- Envoyer des tentatives d'injection SQL (même si vous utilisez un ORM)
- Envoyer des charges XSS dans les champs de chaîne
- Envoyer des types de données non correspondants (chaîne là où un nombre est attendu, etc.)
Je sais ce que vous pensez : "Sarah, c'est fou. Personne n'a le temps pour tout ça." Mais - j'ai automatisé l'ensemble de cette liste de vérification. J'ai un générateur de données de test qui produit toutes ces variations automatiquement. La configuration initiale m'a pris environ deux semaines à construire, mais maintenant je peux exécuter l'ensemble de cette suite contre un nouveau point de terminaison en environ 15 minutes.
Le bénéfice est réel. Le mois dernier, cette liste de vérification a attrapé un point de terminaison qui ferait planter l'ensemble du serveur API lorsque vous envoyez une chaîne plus longue que 65 535 caractères. Le développeur avait supposé que la base de données gérerait la validation de longueur, mais la base de données était configurée pour tronquer silencieusement, et le code de l'application essayait de consigner la chaîne complète dans un tampon de taille fixe. Boom - faute de segmentation, serveur en panne.
Pour les champs de date et d'heure, j'ai une sous-liste de vérification spéciale parce qu'ils sont particulièrement terribles :
- Envoyer des dates dans différents formats (ISO 8601, MM/JJ/AAAA, JJ/MM/AAAA, etc.)
- Envoyer des dates invalides (30 février, mois 13, jour 32)
- Envoyer des dates très anciennes (année 1900, année 1)
- Envoyer des dates très futures (année 2100, année 9999)
- Envoyer des dates avec différents décalages horaires
- Envoyer des dates pendant les transitions d'heure d'été
- Envoyer des horodatages avec millisecondes, microsecondes, nanosecondes
Ce point sur l'heure d'été m'a coûté cher deux fois. Deux fois ! Vous penseriez que j'apprendrais, mais c'est un cas limite tellement étrange qu'il est facile d'oublier. J'ai maintenant un test spécifique qui exécute des transactions à 2 heures du matin le jour où les horloges changent, car c'est à ce moment-là que des choses bizarres se produisent.
Validation des Réponses : Faites Confiance, Mais Vérifiez
La plupart des testeurs se concentrent fortement sur les requêtes et à peine jettent un œil aux réponses. C'est à l'envers. Les réponses de votre API sont son contrat avec le monde. S'ils sont incohérents, incomplets ou incorrects, vous avez brisé ce contrat.
| Catégorie de Test | Point d'Échec Commun | Réponse Attendue | Ce Qui Se Passe En Réalité |
|---|---|---|---|
| Aucun Jeton d'Authentification | Gestion des erreurs manquante | 401 Non autorisé | 500 Erreur interne du serveur ou données exposées |
| Jeton Expiré | Logique de validation du jeton | 401 Non autorisé | Erreur 500 ou échec silencieux |
| Jeton Mal Formé | Validation des entrées | 401 Non autorisé | Plantage de l'application ou exposition de la trace de la pile |
| Jeton Valide, Mauvaises Permissions | Vérifications d'autorisation | 403 Interdit | 200 OK avec accès aux données non autorisées |
| Format de Date Invalide | Assainissement des entrées | 400 Mauvaise requête | Échec de la cascade de transactions |
Ma liste de vérification de validation des réponses comprend :
- Vérifier que le code d'état de la réponse correspond au comportement documenté
- Vérifier que l'en-tête content-type de la réponse est correct
- Vérifier que la structure du corps de réponse correspond au schéma
- Vérifier que tous les champs documentés sont présents
- Vérifier qu'aucun champ non documenté n'est présent (cela compte pour la version de l'API)
- Vérifier que les types de données des champs correspondent à la documentation
- Vérifier que les valeurs des champs sont dans les plages documentées
- Vérifier que les horodatages sont dans le bon fuseau horaire
- Vérifier que les métadonnées de pagination sont correctes et cohérentes
- Vérifier que les réponses d'erreur incluent des messages d'erreur utiles
- Vérifier que les réponses d'erreur incluent des codes d'erreur pour une gestion programmatique
Ce penultimate point concernant les messages d'erreur est crucial. J'ai vu des API retourner "Erreur" comme tout le message d'erreur. C'est inutile. Un bon message d'erreur vous dit ce qui a mal tourné, pourquoi cela a mal tourné, et idéalement ce que vous pouvez faire pour le corriger. Comparez ces deux réponses d'erreur :
Mauvais : {"error": "Requête invalide"}
Bon : {"error": "Requête invalide", "message": "Le champ 'email' est requis mais n'a pas été fourni", "code": "MISSING_REQUIRED_FIELD", "field": "email"}
Le second