Die komplizierten Aspekte der JWT-Sicherheit, über die niemand spricht

10.01.2019
-Minuten Lesezeit
Experte für Sicherheit im Internet, Gründer von Pragmatic Web Security

Einführung

Heutzutage arbeitet praktisch jeder Webentwickler auf die eine oder andere Weise mit JSON Web Token (JWT). Die Protokolle OAuth 2.0 und OpenID Connect verwenden sie für den Informationsaustausch. In modernen Anwendungen verfolgen sie den Status zwischen Anfragen. In Backend-Diensten werden sie zur Weitergabe von Autorisierungsinformationen in einer Microservice-Architektur eingesetzt.

Trotz der weiten Verbreitung der JWT sind ihre Sicherheitsmerkmale häufig unklar oder werden missverstanden. Wie wählt man das Signaturschema für ein JWT? Welche sonstigen Merkmale sollten überprüft werden, bevor man ein JWT als vertrauenswürdig einstuft? Wie funktionieren Schlüsselrotation und Schlüsselverwaltung?

Die Antworten auf diese Fragen sind ausschlaggebend für die Sicherheit der Anwendungsarchitektur. In diesem Artikel gehen wir über die typische Darstellung der Verwendung von JWT hinaus. Wir befassen uns mit den schwierigeren Aspekten, die nur selten erwähnt werden, wie unter anderem:
 

  • Symmetrische JWT-Signaturen

  • Asymmetrische JWT-Signaturen

  • JWT-Validierung jenseits von Signaturen

  • Verwaltung kryptographischer Schlüssel

  • Verwendung von JWT in der Praxis
     

Abschließend liefern wir Ihnen eine Art Checkliste für die JWT-Sicherheit, damit Sie auch später einen Überblick über die hier behandelten Best Practices behalten.

 

HINWEIS: Wenn Sie mit den Grundlagen von JWT nicht vertraut sind, empfehlen wir Ihnen die Lektüre einer Einführung in JWT, bevor Sie sich mit diesem Artikel befassen.

Symmetrische JWT-Signaturen

Der Screenshot in Abbildung 1 unten zeigt die Aufgliederung eines JWTs in seine drei Komponenten. Wie Sie sehen können, enthält der mittlere Teil des Tokens die relevanten Daten. Der Header enthält Metadaten über das Token, während die Signatur dazu dient, die Integrität zu gewährleisten. Die Signatur ist wichtig, um die unbefugte Manipulation eines Tokens erkennen zu können.

 

Abbildung 1 Ein mit einem HMAC-Algorithmus signiertes JWT benötigt ein identisches Geheimnis, um die Signatur zu überprüfen.

 

Das funktioniert so:

Wenn ein Dienst ein JWT erzeugt, erstellt er auch eine Signatur. Üblicherweise wird diese Signatur mit einem HMAC-Algorithmus erstellt, der mit einem bestimmten Typ von kryptographischen Funktionen arbeitet. Ein solcher HMAC wird mit dem Präfix „HS“ gekennzeichnet, wie im obigen Beispiel-Token dargestellt.

 

Der HMAC verwendet den Header, die Nutzlast und einen geheimen Schlüssel und generiert eine eindeutige Signatur für alle drei Eingaben. Dieser Prozess ist im linken Teil der Abbildung 2 unten dargestellt.

 

 

 

Abbildung 2 Schematische Darstellung der Generierung und Verifizierung eines JWTs mit einem symmetrischen Schlüssel.

 

Wenn ein Dienst ein eingehendes JWT erhält, muss er die Integrität überprüfen, bevor er die eingebetteten Daten verwendet. Zu diesem Zweck verwendet er den identischen geheimen Schlüssel, um den HMAC des JWTs zu berechnen. Wenn der resultierende HMAC mit der Signatur im Token übereinstimmt, weiß der Dienst, dass alle drei Eingaben in die HMAC-Funktion die gleichen waren wie zuvor.

Wenn die HMACs jedoch nicht übereinstimmen, hat sich etwas geändert. Dass sich der geheime Schlüssel ändert, ist unwahrscheinlich, daher muss eine Änderung des eingehenden JWTs vorliegen. Dem Dienst ist es egal, was sich geändert hat. Er weist das JWT einfach als Ganzes zurück. Dieser Vorgang ist in Abbildung 2 rechts dargestellt.

 

Beschränkungen symmetrischer Signaturen

Das Signaturschema ist nicht besonders kompliziert. Es wird auch typischerweise herangezogen, um Entwicklern die Funktionsweise der JWT zu erklären. Leider verhindern jedoch symmetrische Signaturen den Austausch der JWT mit anderen Diensten. Alle Dienste müssten Zugang zu demselben geheimen Schlüssel erhalten, um die Integrität eines JWTs zu überprüfen. Der Besitz des geheimen Schlüssels reicht aus, um beliebige JWT mit einer gültigen Signatur zu erzeugen.

 

Die Weitergabe des HMAC-Geheimnisses an den Dienst eines Drittanbieters erzeugt jedoch eine breite Sicherheitslücke. Auch der Austausch des Geheimnisses unter verschiedenen Diensten innerhalb einer einzigen Architektur ist wenig empfehlenswert. Wenn alle Dienste denselben Schlüssel verwenden, wird die Kompromittierung eines einzelnen Dienstes sofort zu einem Problem, das die gesamte Architektur betrifft.

 

Statt den geheimen HMAC-Schlüssel weiterzugeben, können Sie auch auf asymmetrische Signaturen umsatteln.

Asymmetrische JWT-Signaturen

Eine asymmetrische Signatur verwendet ein Schlüsselpaar aus einem öffentlichen und einem privaten Schlüssel. Ein solches Schlüsselpaar verfügt über ein einzigartiges Merkmal. Eine mit einem privaten Schlüssel erzeugte Signatur kann mit dem öffentlichen Schlüssel überprüft werden. Wie der Name schon sagt, kann der öffentliche Schlüssel mit anderen Diensten geteilt werden. Abbildung 3 unten zeigt ein JWT mit einer asymmetrischen Signatur.

 

Abbildung 3 Ein mit einem privaten Schlüssel signiertes JWT kann mit dem zugehörigen öffentlichen Schlüssel überprüft werden.

 

Das funktioniert so:

In der folgenden Abbildung 4 ist der Prozess der Signaturerstellung links dargestellt. Die Methode zur Überprüfung der Signatur sehen Sie rechts im Bild.

 

 

 

Wie Sie sehen können, verwendet der Aussteller des Tokens nur den privaten Schlüssel. Dies bedeutet, dass der private Schlüssel an einem Ort aufbewahrt werden kann, der nur dem Aussteller der JWT-Token bekannt ist. Der öffentliche Schlüssel kann hingegen weit verbreitet sein, so dass jeder Nutzer des Tokens dessen Integrität überprüfen kann. Die Algorithmen, die eine solche Signatur erzeugen, sind mit dem Präfix "RS" gekennzeichnet, wie in dem oben gezeigten Beispiel-Token angegeben.

 

Asymmetrische Signaturen in OpenID Connect

OpenID Connect ist eines der am weitesten verbreiteten Protokolle, das mit diesem Signaturschema arbeitet. Wenn Sie z. B. die Funktion „Mit Google anmelden“ verwenden, benutzen Sie OpenID Connect. Am Ende dieses Vorgangs gibt Google der Anwendung ein Identitäts-Token aus. Dieses Identitäts-Token enthält Informationen über Ihre Identität bei Google. Dadurch erfährt die Anwendung, wer Sie sind, und OpenID Connect fungiert als Authentifizierungsprotokoll.

 

Im OpenID Connect-Szenario verwendet Google seinen privaten Schlüssel, um das Identitäts-Token zu signieren. Die Anwendung verwendet den öffentlichen Schlüssel von Google, um seine Integrität zu überprüfen, bevor sie den eingebetteten Daten vertraut.

 

Auch Bereitstellungen in Unternehmen, die OpenID Connect für Single Sign-on (SSO) verwenden, stützen sich auf JWT. Der SSO-Dienst signiert die Token mit einem privaten Schlüssel. Jede konsumierende Anwendung überprüft die Integrität anhand des öffentlichen Schlüssels.

 

 

Vorteile asymmetrischer Signaturen

Asymmetrische Signaturen sind nicht auf OpenID Connect beschränkt. Jedes verteilte Szenario, das JWT verwendet, profitiert von der Verwendung dieses Signaturverfahrens. In einer Microservice-Architektur, in der JWT ausgetauscht werden, kann zum Beispiel jeder Dienst über ein Schlüsselpaar (öffentlich/privat) verfügen. Verglichen mit symmetrischen Signaturen kann dieses Verfahren die Auswirkungen bei einem Angriff auf einen einzelnen Dienst in dieser Architektur erheblich verringern.

 

JWT-Validierung jenseits von Signaturen

Die sichere Verwendung von JWT beschränkt sich nicht nur auf Überprüfung ihrer Signaturen. Neben der Signatur kann das JWT noch einige andere sicherheitsrelevante Merkmale aufweisen. Diese Merkmale liegen in Form von Standardansprüchen vor, die in der Nutzlast des JWTs enthalten sein können.

Der wichtigste Sicherheitsanspruch ist der "exp"-Claim. Der Aussteller verwendet diesen Anspruch, um die Ablaufzeit eines JWTs festzulegen. Liegt das Ablaufdatum in der Vergangenheit, ist das JWT abgelaufen und darf nicht mehr verwendet werden. Ein typischer Anwendungsfall ist ein Identitäts-Token für OpenID Connect, das nach einer bestimmten Zeit abläuft.

Ein zweiter verwandter Anspruch ist der "iat"-Claim. Dieser Anspruch gibt an, wann das JWT ausgestellt wurde. Er wird meist verwendet, damit der Verbraucher des JWTs ermessen kann, ob das Token noch frisch genug ist. Im gegenteiligen Fall kann der Verbraucher das JWT zurückweisen, um ein neu ausgestelltes Token zu erhalten.

Drittens können JWT den "nbf"-Claim enthalten. Diese Abkürzung steht für „not before“ (deutsch: nicht vor). Damit wird der Zeitpunkt angegeben, an dem das JWT gültig wird. Ein JWT kann nur akzeptiert werden, wenn dieser Zeitstempel in der Vergangenheit liegt.

Der vierte sicherheitsrelevante Standardanspruch ist der "iss"-Claim. Dieser Anspruch verweist auf die Identität der Partei, die das JWT ausgestellt hat. Er enthält eine einfache Zeichenkette, deren Wert vom Aussteller bestimmt wird. Der Verbraucher eines JWTs sollte immer kontrollieren, ob der "iss"-Claim mit dem erwarteten Aussteller übereinstimmt (z. B. sso.example.com).

Der fünfte relevante Anspruch ist der "aud"-Claim. Die Abkürzung steht für „Audience“ (Zielgruppe). Der Anspruch zeigt an, für wen dieser Token bestimmt ist. Der Verbraucher eines JWTs sollte immer überprüfen, ob die Zielgruppe mit seiner eigenen ID übereinstimmt. Der Wert dieser Forderung ist wiederum ein String-Wert, der im Ermessen des Ausstellers liegt. In Szenarien mit OAuth 2.0 und OpenID Connect enthält dieser Wert in der Regel die Client-ID (z. B. api.example.com).

Bitte beachten Sie, dass laut der Spezifikation alle diese Ansprüche optional sind. Dennoch ist es sehr empfehlenswert, sie für das Erstellen von JWT in Ihre Anwendung einzubeziehen. In ähnlicher Weise muss ihr Vorhandensein zur Validierung von JWT überprüft werden. Dies kann Missbrauch verhindern, wenn das JWT in irgendeiner Form offengelegt werden sollte.

Nachfolgend finden Sie ein Codebeispiel zur Überprüfung dieser Ansprüche unter Verwendung der verbreiteten "java-jwt"-Bibliothek. Wie Sie sehen, bietet die Bibliothek spezielle Funktionen zur Überprüfung der genannten Ansprüche. Informieren Sie sich in Ihren Bibliotheken, wie Sie diese Ansprüche optimal behandeln können.

Algorithm algorithm = Algorithm.HMAC256(HMAC_KEY);
JWTVerifier verifier = JWT.require(algorithm)                
.withIssuer("sso.pragmaticwebsecurity.com")
     .withAudience("api.pragmaticwebsecurity.com")
     .build();
DecodedJWT verifiedJWT = verifier.verify(token);
         
// Get the subject
verifiedJWT.getSubject();

Verwaltung kryptographischer Schlüssel

Einer der schwierigsten Aufgaben bei der Verwendung von JWT ist der Umgang mit dem kryptographischen Schlüsselmaterial. Kryptografische Schlüssel, die zum Signieren und Verschlüsseln verwendet werden, müssen häufig ausgetauscht werden. Wenn zu viele Operationen mit nur einem Schlüssel durchgeführt werden, wird die Anwendung anfällig für Kryptoanalyse-Angriffe. Leider wird die Schlüsselrotation bei Anwendungen, die JWT verwenden, oft vernachlässigt.

 

Die Schlüsselrotation ist keine einfache Angelegenheit. Sie setzt voraus, dass mehrere Schlüssel gleichzeitig in Verwendung sein können. Darüber hinaus müssen der Aussteller und der Verbraucher die Schlüssel dynamisch abrufen. Werfen wir also einen Blick darauf, wie die Schlüsselverwaltung für JWT in der Praxis gehandhabt werden kann.

 

Identifizieren eines Schlüssels

Die JWT-Spezifikationen sehen ein paar unterschiedliche Optionen zur Identifizierung bestimmter kryptografischer Schlüssel vor. Der am wenigsten komplizierte Mechanismus ist der "kid"-Claim. Dieser Anspruch kann im Header des Tokens ergänzt werden. Er sollte einen String-basierten Schlüsselbezeichner (Schlüssel-ID) enthalten. In Abbildung 5 unten sehen Sie ein Beispiel.

 

 

Mit der Schlüssel-ID kann der Verbraucher eines JWTs den richtigen kryptografischen Schlüssel abrufen, um die Signatur zu validieren. Dieser einfache Mechanismus funktioniert gut, wenn sowohl der Aussteller als auch der Verbraucher Zugriff auf denselben kryptografischen Schlüsselspeicher haben. So können beispielsweise mehrere Dienste, die innerhalb einer Vertrauenszone laufen, auf denselben Schlüsseltresor zugreifen. Die Schlüssel-ID bezeichnet dann entweder einen Schlüssel für einen HMAC-Algorithmus, oder ein öffentliches/privates Schlüsselpaar für asymmetrische Signaturen.

 

In vielen Szenarien wird jedoch eine Konfiguration mit mehr Flexibilität benötigt. Stellen Sie sich vor, Sie müssten ein Identitäts-Token verifizieren, das in einem OpenID Connect-Flow erstellt wurde. Die vom Aussteller verwendeten Schlüssel wechseln häufig. Wenn sich der Aussteller in einer anderen Vertrauenszone befindet, ist es unwahrscheinlich, dass sowohl der Aussteller als auch der Verbraucher auf den gleichen vertrauenswürdigen Schlüsselspeicher zugreifen können. Für Fälle dieser Art bietet die Spezifikation einen Mechanismus für eine dynamischere Konfiguration an.

 

 

Einbetten von Schlüsseln

Eine erste Option zur Verteilung öffentlicher Schlüssel besteht darin, ihn direkt in die Kopfzeile des JWTs einzubetten. Der Verbraucher kann den Schlüssel abrufen und ihn zur Validierung der Signatur verwenden. Die Spezifikation sieht hierfür zwei Mechanismen vor: Der erste ist der "jwk"-Claim, der für die Einbettung eines öffentlichen Schlüssels im JSON-Web-Key-Format vorgesehen ist. Der zweite ist der "x5c"-Claim, der für einen öffentlichen Schlüssel im Format eines X509-Zertifikats vorgesehen ist.


Die Einbettung des Schlüssels in den Token ist eine einfache Möglichkeit der Schlüsselverteilung. Um die Sicherheit dieses Mechanismus zu gewährleisten, muss der Verbraucher des JWTs einschränken, welche Schlüssel er akzeptiert. Andernfalls könnte ein Angreifer Token erzeugen, die mit einem schädlichen privaten Schlüssel signiert sind.

Ein übermäßig gestattender Verbraucher würde dann einfach mit dem eingebetteten öffentlichen Schlüssel die Signatur validieren, die damit gültig wird. Zur Vorbeugung derartiger Probleme muss der Verbraucher den Schlüssel mit einer Reihe von Schlüsseln abgleichen, die in der Whitelist aufgeführt sind. Liegt der Schlüssel in Form eines X509-Zertifikats vor, kann der Verbraucher die Zertifikatsinformationen verwenden, um die Authentizität zu verifizieren.

Verteilen von Schlüsseln

Die zweite Möglichkeit für eine dynamische Verteilung von Schlüssels ist die Verwendung von Schlüssel-URLs. Der "jku"-Claim ist dafür vorgesehen, eine URL aufzunehmen, die auf eine Datei mit Schlüsseln im JSON-Web-Key-Format verweist. Dieser Mechanismus wird häufig in einem OpenID Connect-Kontext zum automatischen Abrufen von Schlüsseln verwendet. Ein Beispiel finden Sie auf dem API-Endpunkt von Google. In ähnlicher Weise wie zuvor beschrieben fungiert der "x5u"-Claim für X509-formatierte Schlüssel.

Die Verwendung einer Schlüssel-URL bietet mehr Flexibilität und die Token sind kleiner. Wie auch beim Einbetten von Schlüsseln muss der Verbraucher einige Vorsichtsmaßnahmen beachten. Der Verbraucher muss sicherstellen, dass die Schlüssel-URL oder die Schlüssel einer vertrauenswürdigen Partei gehören. Eine Möglichkeit besteht darin, eine ganze Schlüssel-URL oder zumindest die Domäne einer Schlüssel-URL auf die Whitelist zu setzen. Ähnlich wie bei eingebetteten Schlüsseln können auch x509-formatierte Schlüssel anhand der im Zertifikat eingebetteten Merkmale authentifiziert werden.

Beachten Sie dabei, dass eine Schlüssel-URL auf eine Datei verweist, die irgendwo auf einem Server gehostet wird. Eine solche Datei kann mehr als nur eine Schlüsseldefinition enthalten. Damit der Verbraucher den richtigen Schlüssel identifizieren kann, wird in der Regel eine Schlüssel-URL mit einem "kid"-Claim kombiniert. In diesem Fall verweist die Schlüssel-ID auf einen der Schlüssel in der Schlüsseldatei.

Abgesehen davon kann der Verbraucher auch einen Caching-Mechanismus für die Schlüssel-URLs verwenden, um die Leistung zu verbessern.

Verwendung von JWT in der Praxis

Bislang haben wir über die technischen Eigenschaften von JWT-Token gesprochen. Die Verwendung von JWT in der Praxis erfordert jedoch eine sorgfältige Prüfung der Sicherheitsmerkmale eines JWTs.

In den meisten Fällen werden JWT in Form von Inhaber-Token verwendet. Ein Inhaber-Token ist ein Token, das von jedem verwendet werden kann, der es besitzt. Folglich reicht es, wenn ein Angreifer ein solches Token erhält, damit er die mit diesem Token verbundenen Rechte missbrauchen kann. In diesem letzten Abschnitt werden wir kurz einige Anwendungsfälle beleuchten.

JWT in OpenID Connect

Wir haben die Verwendung von JWT in OpenID Connect bereits erwähnt. Der Anbieter stellt dem Client ein Identitäts-Token aus. Dieses Identitäts-Token enthält Informationen über die Authentifizierung des Benutzers beim Provider. Das Identitäts-Token ist ein JWT-Token, das mit dem privaten Schlüssel des Providers signiert ist.

OpenID Connect hat große Anstrengungen unternommen, um die Sicherheitsmerkmale der Identitäts-Token zu verbessern. So schreibt das Protokoll beispielsweise die Verwendung der Ansprüche "exp", "iss" und "aud" vor. Außerdem enthält das Token eine Nonce, um Replay-Angriffe zu verhindern. Diese Anforderungen bewirken, dass der Missbrauch eines gestohlenen Identitäts-Tokens erschwert oder sogar ausgeschlossen wird.

 

JWT als OAuth 2.0-Zugangs-Token

Ein OAuth 2.0-Zugangs-Token ist ein weiterer guter Anwendungsfall für ein JWT. Es ermöglicht einer Client-Anwendung den Zugriff auf eine geschützte Ressource, wie z. B. eine API. OAuth 2.0-Zugangs-Token gibt es in zwei Varianten: Referenz-Token und in sich geschlossene Token.

 

Ein Referenz-Token verweist auf serverseitige Metadaten, die vom Autorisierungsserver aufbewahrt werden. Ein Referenz-Token fungiert als Bezeichner, ähnlich wie eine herkömmliche Sitzungskennung (Session-ID).

 

Ein in sich geschlossenes Token liegt als JWT vor. Alle Metadaten sind in der Nutzlast enthalten. Zum Schutz der Daten signiert der Aussteller das Token mit einem privaten Schlüssel.

 

Herkömmliche OAuth 2.0-Token sind Inhaber-Token. Wird eines dieser Token kompromittiert, kann es von demjenigen, der es besitzt, uneingeschränkt genutzt werden. Ein kompromittiertes Referenz-Token kann vom Autorisierungsserver widerrufen werden. Bei in sich geschlossenen Token ist der Widerruf wesentlich schwieriger.

 

Es wird daher dringend empfohlen, die Lebensdauer von Zugangs-Token so kurz wie möglich zu halten. Es ist durchaus üblich, dass Token nach Minuten oder Stunden ablaufen. Ablaufzeiten von mehreren Tagen oder Monaten sind nicht empfohlen. Wenn möglich, sollten kurzlebige Zugangstoken mit Refresh-Token kombiniert werden, um die Sicherheit zu erhöhen.

 

Darüber hinaus sollen moderne Ergänzungen der Spezifikation die Eigenschaften von Inhaber-Token verbessern, indem JWT mit Mechanismen für den Besitznachweis.

 

als Sitzungsobjekte eingeführt werden

Protokolle wie OpenID Connect und OAuth 2.0 sind ein tatkräftiger Versuch, die Schwachstellen von JWT auszumerzen. Leider gibt es auch viele Anwendungen, die JWT in ihre Architektur einbauen, ohne diese Vorsichtsmaßnahmen zu berücksichtigen.

 

Ein konkretes Beispiel ist eine Anwendung, die JWT einsetzt, um den Autorisierungsstatus auf dem Client zu speichern. Dies ermöglicht die Verwendung eines zustandslosen Backends und erleichtert damit die Bereitstellung erheblich.

 

Ein solcher Kunden-seitiger Token ist jedoch ein Inhaber-Token. Ohne eine kurze Ablaufzeit oder einen Widerrufsmechanismus ist ein solches Szenario extrem anfällig.

 

Darauf genauer einzugehen, würde den Rahmen dieses Artikels sprengen. Wenn Sie mehr über diese Themen erfahren möchten, empfehlen wir Ihnen die Lektüre von „Stop using JWT for sessions.“  

 

JWT Security Best Practices

Wie Sie in diesem Artikel erfahren konnten, steckt hinter JWT viel mehr als nur die Verwendung einer symmetrischen Signatur. Für die meisten Anwendungen von JWT braucht man asymmetrische Signaturen, um die Sicherheit zu gewährleisten.

Außerdem ist die Validierung der Signatur eines eingehenden JWT nur der erste Schritt. Als nächstes muss der Verbraucher die Standardansprüche "exp" und "nbf" überprüfen, um sicherzustellen, dass das JWT gültig ist. Die Ansprüche "iss" und "aud" müssen kontrolliert werden, um die Verwendung des JWTs im richtigen Kontext zu prüfen.

Schließlich müssen Sie für die Verwendung von JWT eine angemessene kryptografische Schlüsselverwaltung einrichten. JWT bieten eine Vielzahl von Optionen zur Schlüsselverwaltung. Eine der Möglichkeiten besteht darin, einen bestimmten Schlüssel durch einen Bezeichner zu identifizieren. Weitergehende Optionen ermöglichen die Einbettung eines Schlüssels in das Token oder den Abruf eines Schlüssels von einer speziellen Schlüssel-URL. Unabhängig vom Mechanismus muss der Verbraucher immer die Gültigkeit des Schlüssels überprüfen, bevor er ihm vertraut.

 

Wir haben in diesem Artikel viele Aspekte angesprochen. Diese Checkliste für JWT-Sicherheit bietet einen Überblick über all diese bewährten Verfahren. So können Sie diese Dinge während der Entwicklung Ihrer Anwendung im Auge behalten. Weitere Informationen über die Sicherung von APIs mithilfe von offenen Standard-Protokollen finden Sie in unserem Whitepaper „How to Extend Identity Security to your APIs.“

 

Diesen Artikel teilen:
Verwandte Ressourcen

Starten Sie jetzt

Kontaktieren Sie uns

sales@pingidentity.com

Erfahren Sie, wie Ping Ihnen helfen kann, sichere Erlebnisse für Mitarbeiter, Partner und Kunden in einer sich schnell wandelnden digitalen Welt zu bieten.