Best Practices für die API-Sicherheit Verify

Die Vonage Verify API ist ein sicherer, zuverlässiger Dienst zur Telefonnummernüberprüfung und zur Multi-Faktor-Authentifizierung (MFA). Wie bei jedem Authentifizierungssystem hängt die Gesamtsicherheit jedoch gleichermaßen davon ab, wie Ihre Backend-Application in das System integriert ist. In diesem Leitfaden werden die wichtigsten Sicherheitsaspekte erläutert, die Sie bei Ihrer eigenen Implementierung berücksichtigen müssen, um Ihre Nutzer zu schützen.

Anmerkung: Die in diesem Leitfaden beschriebenen Best Practices gelten für alle Verify-API-Kanäle, einschließlich SMS, Sprache, WhatsApp, Silent Authentication und aller anderen unterstützten Kanäle. Auch wenn sich einige Beispiele auf Silent-Authentication-Abläufe beziehen, sind die zugrunde liegenden Prinzipien universell gültig.

Das Vertrauensmodell verstehen

Die Vonage Verify API erfüllt eine bestimmte Funktion: Sie überprüft, ob eine bestimmte request_id und code Das Paar ist korrekt. Es lässt sich jedoch nicht feststellen, ob die Person, die dieses Paar übermittelt, dieselbe Person ist, die ursprünglich die Verifizierungsanfrage ausgelöst hat.

Dies ist ein entscheidender Unterschied. Die Verify-API arbeitet auf Netzwerkebene – sie hat keinerlei Kenntnis von Ihren Benutzersitzungen, Ihrem Anmeldestatus oder dem Anwendungskontext. Ihr Backend ist dafür zuständig, eine Verifizierungsanfrage einem bestimmten Benutzer und einer bestimmten Sitzung zuzuordnen. Wenn Ihr Backend diese Bindung nicht erzwingt, kann ein Angreifer, der eine gültige request_id und code Ein Paar (aus einer anderen Sitzung, einer früheren Anfrage oder durch das Abfangen eines clientseitigen Datenflusses) kann damit eine Authentifizierung als jede beliebige Ziel-Telefonnummer vornehmen.

Das Sicherheitsmodell sollte daher als zwei sich ergänzende Ebenen verstanden werden:

  • Die Verantwortung von Vonage: Erzeugung einer kryptografisch korrekten code, es sicher zu übermitteln und die request_id/code Paar.
  • Ihre Verantwortung: Sicherstellen, dass die request_id und code Zur Überprüfung eingereicht werden diejenigen, die Ihr Backend für den authentifizierten Benutzer in der aktuellen Sitzung initiiert hat.

Die Überprüfung stets serverseitig einleiten

Lassen Sie niemals zu, dass Ihre Client-Anwendung (mobile App, Browser oder Frontend) eine Verifizierungsanfrage direkt an die Vonage Verify-API sendet. Alle Aufrufe an POST /v2/verify muss von Ihrem Backend-Server aus erfolgen.

Dadurch wird sichergestellt, dass:

  • Ihre API-Zugangsdaten werden dem Kunden gegenüber niemals offengelegt.
  • Die bei der Verifizierung verwendete Telefonnummer ist diejenige, die in Ihrem System für diesen Benutzer gespeichert ist – und nicht ein Wert, der vom Client zur Laufzeit übermittelt wird.
  • Ihr Backend behält die volle Kontrolle über den gesamten Verifizierungszyklus.

Falsches Muster (Tu das nicht):

Client → POST /v2/verify (directly to Vonage, with phone number from user input)

Richtiges Muster:

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

Speichern Sie die `request_id` serverseitig und verknüpfen Sie sie mit der Benutzersitzung

Wenn die Vonage Verify-API auf eine Anfrage zum Start der Verifizierung reagiert, gibt sie einen request_id. Dieser Wert muss sicher in Ihrem Backend gespeichert werden – beispielsweise in einer serverseitigen Sitzung oder einem Datenbankdatensatz – und explizit mit folgendem verknüpft werden:

  • Der jeweilige Benutzer oder der jeweilige Account, der die Überprüfung auslöst.
  • Die Telefonnummer wird gerade verifiziert.
  • Die aktuelle Authentifizierungssitzung oder Transaktion.

Wenn der Client anschließend einen Code zur Überprüfung übermittelt, muss Ihr Backend:

  1. Rufe die request_id aus der eigenen Sitzung/Datenbank (nicht vom Client).
  2. Rufen Sie an. POST /v2/verify/{request_id} unter ausschließlicher Verwendung der auf dem Server gespeicherten request_id.

Akzeptiere niemals die request_id als Eingabe vom Kunden. Wenn Ihr Backend die request_id aus einer Client-Anfrage und leitet diese direkt an Vonage weiter, kann ein Angreifer eine request_id aus einer früheren gültigen Überprüfung – einschließlich einer für eine andere Telefonnummer oder einen anderen Nutzer – und die API gibt eine erfolgreiche Validierung zurück.

Beispiel für eine korrekte Implementierung (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 });
  }
});

Vertrauen Sie bei Sicherheitsentscheidungen niemals auf vom Client bereitgestellte Parameter

Ihre Client-Anwendung sendet im Rahmen des Verifizierungsablaufs möglicherweise Daten an Ihr Backend (zum Beispiel eine request_id (wird zur Verwendung bei einer „Silent Authentication“-Weiterleitung an den Client zurückgegeben). Behandeln Sie alle derartigen Werte als nicht vertrauenswürdige Eingabe:

  • Nicht Verwenden Sie eine vom Kunden bereitgestellte request_id um den Endpunkt „Verify check“ aufzurufen.
  • Nicht Verwenden Sie eine vom Kunden angegebene Telefonnummer, um zu bestimmen, welcher Benutzer verifiziert wird.
  • Nicht sich auf den clientseitigen Status stützen, um festzustellen, ob eine Überprüfung erfolgreich war.

Die Rolle des Clients beschränkt sich darauf, Aktionen in Ihrem Backend auszulösen (über authentifizierte API-Aufrufe an Ihren eigenen Server) und im Falle der stillen Authentifizierung die check_url Weiterleitung über das Netz des Mobilfunkanbieters. Ihr Backend muss das Ergebnis eigenständig nachverfolgen und Verify.

Einführung eines Lebenszyklusmanagements für die sitzungsbezogene Verifizierung

Jeder Verifizierungsversuch sollte auf eine einzelne Sitzung und einen einzelnen Benutzer beschränkt sein. Implementieren Sie die folgenden Lebenszyklus-Kontrollen in Ihrem Backend:

  • Eine aktive Anfrage pro Benutzer: Bevor Sie eine neue Überprüfung starten, prüfen Sie, ob eine ausstehende request_id für diesen Benutzer bereits vorhanden ist. Brechen Sie diese ab oder lassen Sie sie ablaufen, bevor Sie eine neue anlegen.
  • Kurze Gültigkeitsdauer für ausstehende Anfragen: Wenn der Benutzer die Verifizierung nicht innerhalb eines angemessenen Zeitraums (z. B. 5 Minuten) abschließt, soll die in der Sitzung gespeicherte request_id in Ihrem Backend und erfordern eine erneute Überprüfung, bevor Sie beginnen können.
  • Einmalverbrauch: Sobald die Überprüfung erfolgreich abgeschlossen ist, entfernen Sie unverzüglich die request_id aus Ihrer Sitzung/Datenbank. Ein abgeschlossener request_id sollten innerhalb Ihrer Anwendung niemals wiederverwendbar sein.
  • Bei fehlgeschlagenen Versuchen ungültig machen: Nach einer konfigurierbaren Anzahl fehlgeschlagener Code-Eingaben soll die Verifizierungsanfrage abgebrochen und der Benutzer aufgefordert werden, den Vorgang erneut zu starten.

Ratenbegrenzung auf Anwendungsebene anwenden

Die Vonage Verify-API verfügt zwar über integrierte Schutzmaßnahmen gegen Betrug, Sie sollten jedoch zusätzlich in Ihrer eigenen Anwendung eine Ratenbegrenzung implementieren, um das Risiko von Enumerations-, Flooding- oder Brute-Force-Angriffen zu verringern:

  • Anzahl der Verifizierungsanfragen pro Telefonnummer begrenzen: Begrenzen Sie die Anzahl der Verifizierungsanfragen, die innerhalb eines bestimmten Zeitfensters für eine bestimmte Telefonnummer gestellt werden können (z. B. nicht mehr als 3 Anfragen pro Stunde).
  • Anzahl der Anfragen pro Account oder IP-Adresse begrenzen: Es soll verhindert werden, dass ein einzelner Account oder eine einzelne Quelle eine übermäßige Anzahl von Verifizierungsanfragen auslöst.

Diese Kontrollmechanismen unterscheiden sich von dem auf Plattformebene implementierten System zur Ratenbegrenzung und Betrugsbekämpfung von Vonage und ergänzen dieses. Weitere Informationen zu den integrierten Betrugsschutzmaßnahmen von Vonage finden Sie unter Leitfaden zum Betrugsbekämpfungssystem.

Trennung von Registrierung und Überprüfung

In typischen Anwendungen gibt es zwei unterschiedliche Fälle, in denen eine Telefonnummernüberprüfung zum Einsatz kommt:

  1. Anmeldung (Registrierung einer Telefonnummer für die Zwei-Faktor-Authentifizierung): Der Benutzer fügt seinem Account eine neue Telefonnummer hinzu. Dies erfolgt in der Regel einmalig und muss mit dem Kontodatensatz des authentifizierten Benutzers verknüpft werden.
  2. Überprüfung (bei der Anmeldung mit 2FA): Der Benutzer weist nach, dass er nach wie vor Inhaber der bei der Registrierung hinterlegten Telefonnummer ist.

Diese beiden Abläufe erfordern unterschiedliche Sicherheitsmaßnahmen:

Während Anmeldung, stellen Sie sicher, dass die zu registrierende Telefonnummer nicht bereits einem anderen Account zugeordnet ist, und vergewissern Sie sich, dass der Benutzer authentifiziert ist, bevor Sie die Nummer hinzufügen.

Während Überprüfung bei der Anmeldung, stellen Sie sicher, dass die in der Verify-API-Anfrage verwendete Telefonnummer mit der in Ihrer Datenbank für diesen Benutzer gespeicherten Nummer übereinstimmt – niemals mit der vom Kunden bei der Anmeldung angegebenen Nummer. Ein Angreifer, der die Telefonnummer eines Benutzers kennt, sollte nicht in der Lage sein, in dessen Namen eine Verifizierungsanfrage auszulösen.

Weitere Hinweise zur stillen Authentifizierung

Die „Silent Authentication“ führt einen speziellen, mehrstufigen Umleitungsablauf ein, bei dem die check_url muss vom Mobilgerät des Nutzers über das Netz des Mobilfunkanbieters verfolgt werden. Dabei ist besondere Vorsicht geboten:

  • Bewahren Sie das request_id sofort nach dem Anruf /v2/verify und bevor eine Antwort an den Client zurückgesendet wird. Verknüpfen Sie diese mit der Benutzersitzung, wie in der Bewahren Sie das request_id Serverseitig und an die Benutzersitzung binden.
  • Überschreiten Sie nicht die request_id an den Kunden es sei denn, dies ist für den Umleitungsablauf der stillen Authentifizierung unbedingt erforderlich. Falls Sie den Parameter übergeben müssen (damit der Client dem check_url), behandeln Sie ihn als kurzlebiges Einmal-Token und Verify ihn im Rahmen des Code-Check-Schritts anhand Ihrer Sitzung.
  • Mobilfunkdaten für die Weiterleitung erzwingen: Die check_url muss über das Mobilfunknetz des Netzbetreibers erfolgen, nicht über WLAN. Wenn die Anfrage über WLAN gestellt wird, führt dies zu einem Fehler und der Nachweis des SIM-Besitzes auf Netzbetreiberebene geht verloren. Verwenden Sie das Vonage-SDK für Android oder iOS, um dies bei der Entwicklung nativer mobiler Apps durchzusetzen. Die SDKs bieten außerdem integrierte Konnektivitätsprüfungen, Timeout-Verwaltung bei Weiterleitungen (bis zu 10 Weiterleitungen mit jeweils 5 Sekunden Timeout) sowie typisierte Ausnahmen, mit denen Sie präzise auf Fehler reagieren können. Siehe die Leitfaden für bewährte Praktiken der stillen Authentifizierung für Details zur Umsetzung.
  • Überprüfen Sie vor dem Start der stillen Authentifizierung, ob eine Mobilfunkverbindung besteht: Wenn das Gerät keine aktive mobile Datenverbindung hat, starten Sie den Schritt „Silent Authentication“ nicht. Fahren Sie stattdessen direkt mit dem nächsten Kanal in Ihrem Workflow fort (SMS, Sprache usw.). Der Start einer „Silent Authentication“-Anfrage ohne mobile Datenverbindung schlägt fehl und verursacht unnötige Verzögerungen, bevor der Fallback-Kanal erreicht wird. Das Vonage SDK löst einen sdk_no_data_connectivity Ausnahme, wenn diese Bedingung während der Ausführung festgestellt wird – Ihre App sollte dies abfangen und sofort reagieren, anstatt auf das standardmäßige Timeout von 60 Sekunden zu warten.
  • SDK-Ausnahmen behandeln und das Backend-Failover umgehend auslösen: Wenn das SDK während des „Silent Authentication“-Ablaufs eine Ausnahme auslöst (zum Beispiel, sdk_no_data_connectivity, sdk_connection_error, oder sdk_redirect_error), muss Ihre mobile App Ihr Backend unverzüglich benachrichtigen. Ihr Backend sollte dann die POST /v2/verify/{request_id}/next_workflow Endpunkt, um die Verifizierung ohne Wartezeit auf den nächsten Kanal fortzusetzen. Wenn keine Aktion erfolgt, läuft die Plattform nach 60 Sekunden automatisch ab und wechselt zum nächsten Workflow – wenn Sie dies jedoch über Ihr Backend auslösen, wird die Wartezeit für den Benutzer sofort minimiert und Sie behalten die Kontrolle über den Verifizierungszyklus, im Einklang mit der Einführung eines Lebenszyklusmanagements für die sitzungsbezogene Verifizierung. Verlassen Sie sich nicht darauf, dass der Client das Problem selbst behebt: Die Ausnahmebehandlung muss zu einem vom Backend gesteuerten Zustandswechsel führen.
  • Überprüfen Sie das Ergebnis immer serverseitig.: Verlassen Sie sich nicht auf einen vom Client gemeldeten Erfolg der „Silent Authentication“-Weiterleitung. Ihr Backend sollte den endgültigen Verifizierungsstatus erhalten und die Autorisierungsentscheidung eigenständig treffen.

Zusammenfassung der Checkliste

Bevor Sie eine Verify-API-Integration in der Produktion bereitstellen, überprüfen Sie bitte Folgendes:

  • Alle Aufrufe von POST /v2/verify werden ausschließlich serverseitig durchgeführt.
  • Die Telefonnummer in der Bestätigungsanfrage stammt aus Ihrer Datenbank und nicht aus einer Eingabe des Kunden.
  • Die request_id wird serverseitig gespeichert (in einer Sitzung oder in der Datenbank) und niemals vom Client akzeptiert.
  • Die request_id ist an den jeweiligen Benutzer und die jeweilige Sitzung gebunden, die die Überprüfung ausgelöst haben.
  • Ausstehende Überprüfungen werden nach Ablauf einer bestimmten Frist ungültig.
  • Abgeschlossene oder fehlgeschlagene Überprüfungen werden umgehend bereinigt.
  • Pro Telefonnummer, pro Benutzer und pro IP-Adresse ist eine Ratenbegrenzung auf Anwendungsebene eingerichtet.
  • Die Abläufe für die Registrierung und die Anmeldeüberprüfung werden separat mit unterschiedlichen Sicherheitsprüfungen abgewickelt.
  • Die Umleitungsabläufe bei der stillen Authentifizierung erfolgen über Mobilfunkdaten, und die Ergebnisse werden serverseitig bestätigt.

Weiterführende Ressourcen