Verify les bonnes pratiques en matière de sécurité des API
L'API Vonage Verify est un service sécurisé et fiable destiné à la vérification des numéros de téléphone et à l'authentification multifactorielle (MFA). Cependant, comme tout système d'authentification, sa sécurité globale dépend tout autant de la manière dont votre application backend s'y intègre. Ce guide présente les principales considérations de sécurité que vous devez prendre en compte dans votre propre implémentation afin de protéger vos utilisateurs.
Remarque : Les bonnes pratiques présentées dans ce guide s'appliquent à tous les canaux de l'API Verify, notamment les SMS, les appels vocaux, WhatsApp, l'authentification silencieuse et tout autre canal pris en charge. Bien que certains exemples fassent référence aux flux d'authentification silencieuse, les principes sous-jacents sont universels.
Comprendre le modèle de confiance
L'API Vonage Verify remplit une fonction spécifique : elle vérifie si un request_id et code La paire est correcte. Ce qu’il ne peut pas faire, c’est déterminer si la personne qui soumet cette paire est bien celle qui a initialement déclenché la demande de vérification.
Il s'agit là d'une distinction essentielle. L'API Verify fonctionne au niveau du réseau : elle n'a aucune information concernant vos sessions utilisateur, votre état de connexion ou le contexte de l'application. Votre backend est chargé d'associer une demande de vérification à un utilisateur et à une session spécifiques. Si votre backend n'impose pas cette contrainte, un attaquant qui parvient à obtenir un request_id et code (provenant d'une autre session, d'une requête précédente ou en interceptant un flux côté client) peut l'utiliser pour s'authentifier en se faisant passer pour n'importe quel numéro de téléphone de son choix.
Le modèle de sécurité doit donc être considéré comme composé de deux couches complémentaires :
- Responsabilité de Vonage: Génération d'un élément cryptographiquement correct
code, en l'acheminant en toute sécurité et en vérifiant larequest_id/codepaire. - Votre responsabilité: Veiller à ce que le
request_idetcodeLes requêtes soumises pour vérification sont celles que votre backend a lancées pour l'utilisateur authentifié au cours de la session en cours.
Toujours lancer la vérification côté serveur
Ne laissez jamais votre application cliente (application mobile, navigateur ou interface utilisateur) envoyer une requête de vérification directement à l'API Vonage Verify. Tous les appels vers POST /v2/verify doit être effectuée depuis votre serveur backend.
Cela garantit que :
- Vos identifiants d'API ne sont jamais communiqués au client.
- Le numéro de téléphone utilisé pour la vérification est celui enregistré dans votre système pour cet utilisateur — et non une valeur fournie par le client au moment de l'exécution.
- Votre backend conserve le contrôle total du cycle de vérification.
Motif incorrect (à ne pas faire) :
Client → POST /v2/verify (directly to Vonage, with phone number from user input)
Modèle correct:
Client → POST /your-backend/start-verification
Backend → POST /v2/verify (to Vonage, using phone number from your database)
Backend stores request_id in session/database
Backend → returns request_id (or nothing) to client
Enregistrer l'`request_id` côté serveur et l'associer à la session de l'utilisateur
Lorsque l'API Vonage Verify répond à une requête de lancement de vérification, elle renvoie un request_id. Cette valeur doit être stockée en toute sécurité sur votre backend — par exemple, dans une session côté serveur ou dans un enregistrement de base de données — et explicitement associée à :
- L'utilisateur ou l'Account spécifique à l'origine de la vérification.
- Le numéro de téléphone est en cours de vérification.
- La session ou la transaction d'authentification en cours.
Lorsque le client soumet ensuite un code à des fins de vérification, votre backend doit :
- Récupérer le
request_idà partir de sa propre session/base de données (et non à partir du client). - Appeler
POST /v2/verify/{request_id}en utilisant uniquement les données stockées sur le serveurrequest_id.
N'acceptez jamais le request_id sous forme de données fournies par le client. Si votre backend utilise le request_id à partir d'une requête client et la transmet directement à Vonage, un pirate peut fournir un request_id à partir de toute vérification valide antérieure — y compris celle effectuée pour un autre numéro de téléphone ou un autre utilisateur — et l'API renverra une validation réussie.
Exemple d'implémentation correcte (Node.js/Express):
// Start verification — called from your app backend only
app.post('/start-verification', async (req, res) => {
const user = await getUserFromSession(req.session.userId);
// Phone number comes from YOUR database, not the client request
const { request_id } = await vonage.verify.start({
brand: 'YourApp',
workflow: [{ channel: 'sms', to: user.phoneNumber }]
});
// Store request_id server-side, bound to the user session
req.session.pendingVerification = {
request_id,
phoneNumber: user.phoneNumber,
userId: user.id,
createdAt: Date.now()
};
res.json({ status: 'verification_started' });
});
// Check code — request_id is retrieved from session, never from client
app.post('/check-code', async (req, res) => {
const { code } = req.body;
const pending = req.session.pendingVerification;
if (!pending || !pending.request_id) {
return res.status(400).json({ error: 'No active verification for this session' });
}
const result = await vonage.verify.check(pending.request_id, code);
if (result.status === 'completed') {
// Clear the pending verification after success
delete req.session.pendingVerification;
res.json({ verified: true });
} else {
res.status(401).json({ verified: false });
}
});
Ne vous fiez jamais aux paramètres fournis par le client pour prendre des décisions en matière de sécurité
Votre application cliente peut envoyer des données à votre serveur dans le cadre du processus de vérification (par exemple, un request_id renvoyées au client pour être utilisées dans une redirection avec authentification silencieuse). Traitez toutes ces valeurs comme des données non fiables :
- Ne pas utiliser un fichier fourni par le client
request_idpour appeler le point de terminaison de vérification « Verify ». - Ne pas utiliser un numéro de téléphone fourni par le client pour déterminer quel utilisateur doit être vérifié.
- Ne pas s'appuient sur l'état côté client pour déterminer si une vérification a abouti.
Le rôle du client se limite à : déclencher des actions dans votre backend (via des appels API authentifiés vers votre propre serveur) et, dans le cas de l'authentification silencieuse, à exécuter le check_url rediriger via le réseau de l'opérateur mobile. Votre système backend doit suivre et vérifier le résultat de manière indépendante.
Mettre en œuvre la gestion du cycle de vie de la vérification par session
Chaque tentative de vérification doit être limitée à une seule session et à un seul utilisateur. Mettez en œuvre les contrôles de cycle de vie suivants dans votre backend :
- Une requête active par utilisateur: Avant de lancer une nouvelle vérification, vérifiez s'il y a une vérification en attente
request_idexiste déjà pour cet utilisateur. Annulez-le ou laissez-le expirer avant d'en créer un nouveau. - Délai d'expiration court pour les demandes en attente: Si l'utilisateur ne termine pas la vérification dans un délai raisonnable (par exemple, 5 minutes), invalidez les données stockées dans la session
request_idsur votre backend et nécessitent une nouvelle vérification pour démarrer. - Consommation à usage unique: Une fois la vérification terminée avec succès, supprimez immédiatement le
request_idà partir de votre session/base de données. Une fois terminé,request_idne devraient jamais être réutilisables au sein de votre application. - Invalider en cas d'échecs successifs: Après un nombre configurable d'échecs lors de la saisie du code, annuler la demande de vérification et demander à l'utilisateur de recommencer.
Appliquer la limitation de débit au niveau de l'application
Bien que l'API Vonage Verify intègre des protections anti-fraude, vous devez également mettre en place une limitation de débit dans votre propre application afin de réduire le risque d'attaques par énumération, par inondation ou par force brute :
- Limiter le nombre de demandes de vérification par numéro de téléphone: Limiter le nombre de demandes de vérification pouvant être lancées pour un numéro de téléphone donné au cours d'un intervalle de temps donné (par exemple, pas plus de 3 demandes par heure).
- Limiter le nombre de requêtes par compte utilisateur ou par adresse IP: Empêcher qu'un seul compte ou une seule source ne génère un nombre excessif de demandes de vérification.
Ces contrôles sont distincts — et complémentaires — du système de limitation de débit et de lutte contre la fraude intégré à la plateforme de Vonage. Pour plus d'informations sur les protections anti-fraude intégrées de Vonage, consultez le Guide du système de lutte contre la fraude.
Distinguer l'inscription de la vérification
Dans les applications classiques, la vérification du numéro de téléphone intervient à deux moments bien distincts :
- Inscription (enregistrement d'un numéro de téléphone pour l'authentification à deux facteurs) : L'utilisateur ajoute un nouveau numéro de téléphone à son compte. Cette opération ne s'effectue généralement qu'une seule fois et doit être associée à la fiche de l'utilisateur authentifié.
- Vérification (en utilisant l'authentification à deux facteurs lors de la connexion) : L'utilisateur prouve qu'il est toujours en possession du numéro de téléphone enregistré lors de son inscription.
Ces deux flux nécessitent des mesures de sécurité différentes :
Au cours de inscription, vérifiez que le numéro de téléphone à enregistrer n'est pas déjà associé à un autre compte, et assurez-vous que l'utilisateur est authentifié avant d'ajouter ce numéro.
Au cours de vérification lors de la connexion, assurez-vous que le numéro de téléphone utilisé dans la requête de l'API Verify corresponde à celui enregistré dans votre base de données pour cet utilisateur — et en aucun cas à celui fourni par le client lors de la connexion. Un pirate connaissant le numéro de téléphone d'un utilisateur ne doit pas pouvoir déclencher une demande de vérification en son nom.
Consignes supplémentaires concernant l'authentification silencieuse
L'authentification silencieuse met en place un flux de redirection spécifique en plusieurs étapes dans lequel le check_url doit être suivi par l'appareil mobile de l'utilisateur via le réseau de l'opérateur. Il convient de faire preuve d'une attention particulière :
- Conservez le
request_idimmédiatement après avoir appelé/v2/verifyet avant de renvoyer une réponse au client. Associez-le à la session de l'utilisateur comme décrit dans le Conservez lerequest_idCôté serveur et l'associer à la session utilisateur. - Ne dépassez pas le
request_idau client sauf si cela est strictement nécessaire pour le flux de redirection de l'authentification silencieuse. Si vous devez le transmettre (pour que le client suive lecheck_url), considérez-le comme un jeton à durée de vie limitée et à usage unique, et vérifiez-le par rapport à votre session lors de l'étape de validation du code. - Forcer l'utilisation des données mobiles pour la redirection: Le
check_urldoit être effectuée via le réseau de l'opérateur mobile, et non via le Wi-Fi. Si la requête est effectuée via le Wi-Fi, elle entraînera une erreur et la preuve de possession de la carte SIM au niveau de l'opérateur sera perdue. Utilisez le SDK Vonage pour Android ou iOS afin d'appliquer cette règle lors du développement d'applications mobiles natives. Les SDK fournissent également des contrôles de connectivité intégrés, la gestion des délais d’expiration lors des redirections (jusqu’à 10 redirections, avec un délai d’expiration de 5 secondes chacune), ainsi que des exceptions typées qui vous permettent de réagir avec précision aux échecs. Consultez le Guide des meilleures pratiques en matière d'authentification silencieuse pour plus de détails sur la mise en œuvre. - Vérifiez que la connexion de données mobiles est active avant de lancer l'authentification silencieuse : Si l'appareil ne dispose pas d'une connexion de données mobiles active, ne lancez pas l'étape d'authentification silencieuse. Passez plutôt directement au canal suivant de votre flux de travail (SMS, voix, etc.). Le lancement d'une demande d'authentification silencieuse sans connexion de données mobiles échouera et ajoutera une latence inutile avant que le canal de secours ne soit atteint. Le SDK Vonage génère une
sdk_no_data_connectivityexception lorsque cette condition est détectée pendant l'exécution — votre application doit la détecter et réagir immédiatement, plutôt que d'attendre l'expiration du délai par défaut de 60 secondes. - Gérer les exceptions du SDK et déclencher rapidement le basculement vers le backend : Si le SDK lève une exception au cours du processus d'authentification silencieuse (par exemple,
sdk_no_data_connectivity,sdk_connection_errorousdk_redirect_error), votre application mobile doit immédiatement en informer votre serveur. Votre serveur doit alors appeler laPOST /v2/verify/{request_id}/next_workflowpoint de terminaison pour faire passer la vérification au canal suivant sans attendre. Si aucune action n'est effectuée, la plateforme expirera automatiquement au bout de 60 secondes et passera au workflow suivant — mais le fait de déclencher cette opération depuis votre backend réduit immédiatement le temps d'attente de l'utilisateur et vous permet de garder le contrôle sur le cycle de vie de la vérification, conformément à la Mettre en œuvre la gestion du cycle de vie de la vérification par session. Ne comptez pas sur le client pour résoudre le problème de lui-même : la gestion des exceptions doit entraîner une transition d'état pilotée par le backend. - Vérifiez toujours le résultat côté serveur: Ne vous fiez pas à la réussite signalée par le client suite à la redirection de l'authentification silencieuse. Votre backend doit recevoir le statut de vérification final et prendre la décision d'autorisation de manière indépendante.
Liste de contrôle du résumé
Avant de déployer une intégration de l'API Verify en production, veuillez vérifier les points suivants :
- Tous les appels vers
POST /v2/verifysont effectuées uniquement côté serveur. - Le numéro de téléphone figurant dans la demande de vérification provient de votre base de données, et non d'une saisie effectuée par le client.
- Les
request_idest stockée côté serveur (en session ou dans une base de données) et n'est jamais acceptée depuis le client. - Les
request_idest associé à l'utilisateur et à la session spécifiques qui ont lancé la vérification. - Les vérifications en attente sont annulées passé un certain délai.
- Les vérifications terminées ou ayant échoué sont immédiatement supprimées.
- Une limitation de débit au niveau des applications est mise en place par numéro de téléphone, par utilisateur et par adresse IP.
- Les processus d'inscription et de vérification de connexion sont gérés séparément et font l'objet de contrôles de sécurité distincts.
- Les flux de redirection liés à l'authentification silencieuse s'effectuent via le réseau mobile et les résultats sont validés côté serveur.