Lesen Sie bitte die Antwort von Joachim, bevor Sie diese lesen . Er deckt die allgemeinen Gründe für die clientseitige Sicherheitslücke ab. Nun zu einem Vorschlag, wie Sie dieses Problem umgehen könnten ...
Ein sicheres Schema für die Client-Server-Kommunikation, ohne sich bei jeder Anforderung manuell beim Server authentifizieren zu müssen:
Sie sind immer noch im Stich gelassen der Server das letzte Wort haben, und der Server noch alles validieren der Kunde sagt, aber es geschieht transparent.
Nehmen Sie das HTTPS- Protokoll an, um Man-in-the-Middle-Angriffe (MITMA) zu verhindern.
Der Client gibt zum ersten Mal einen Handshake mit dem Server aus, und der Server generiert einen öffentlichen Schlüssel für den Client und behält einen privaten Schlüssel bei, der ein asymmetrisches Verschlüsselungsschema verwendet. Der Client speichert den "öffentlichen" Schlüssel des Servers im lokalen Speicher, verschlüsselt mit einem sicheren Passwort, das Sie nirgendwo speichern.
Der Client ist jetzt offline. Der Client möchte vertrauenswürdige Aktionen ausführen. Der Client gibt sein Passwort ein und greift nach dem öffentlichen Schlüssel des Servers.
Der Client führt jetzt Aktionen basierend auf dem Wissen über diese Daten aus, und der Client verschlüsselt jede Aktion, die er ausführt, mit dem öffentlichen Schlüssel des Servers für diesen Client .
Wenn der Client online ist, sendet der Client seine Client-ID und alle vom Client ausgeführten Aktionen werden verschlüsselt mit dem öffentlichen Schlüssel des Servers an den Server gesendet.
Der Server entschlüsselt die Aktionen und vertraut bei korrektem Format darauf, dass sie vom Client stammen.
Hinweis:
Sie können das Clientkennwort nirgendwo speichern, da ein Angreifer sonst den Schlüssel abrufen und die Aktionen als seine eigenen signieren könnte. Die Sicherheit dieses Schemas hängt ausschließlich von der Integrität des Schlüssels ab, den der Server für den Client generiert. Der Client muss weiterhin beim Server authentifiziert werden, wenn er nach diesem Schlüssel fragt.
Tatsächlich verlassen Sie sich aus Sicherheitsgründen immer noch auf den Server und nicht auf den Client. Jede Aktion, die der Client ausführt, muss auf dem Server überprüft werden.
Es ist möglich, externe Skripte in Web Workern auszuführen . Denken Sie daran, dass jede JSONP- Anfrage, die Sie haben, jetzt ein viel größeres Sicherheitsproblem darstellt. Sie müssen den Schlüssel um jeden Preis schützen. Sobald Sie es verlieren, kann sich ein Angreifer als Benutzer ausgeben.
Dies entspricht Ihrer Anforderung, dass kein Ping an den Server ausgeführt wird. Ein Angreifer kann eine HTTP-Anfrage mit gefälschten Daten nicht einfach imitieren, wenn er den Schlüssel nicht kennt.
Die Antwort von Joachim ist immer noch richtig . Tatsächlich führen Sie immer noch die gesamte Authentifizierung auf dem Server durch . Das Einzige, was Sie hier gespeichert haben, ist die Notwendigkeit, das Passwort jedes Mal beim Server zu überprüfen. Sie müssen jetzt nur den Server einbeziehen, wenn Sie ein Commit durchführen oder aktualisierte Daten abrufen möchten. Wir haben hier lediglich einen vertrauenswürdigen Schlüssel auf der Clientseite gespeichert und den Client erneut validieren lassen.
Dies ist ein recht verbreitetes Schema für Anwendungen mit nur einer Seite (z. B. mit AngularJS).
Ich bezeichne den öffentlichen Schlüssel des Servers als "öffentlich", da dies in Schemata wie RSA bedeutet , aber es handelt sich tatsächlich um vertrauliche Informationen im Schema, die geschützt werden sollten.
Ich würde das Passwort nirgendwo im Speicher behalten. Ich würde den Benutzer veranlassen, jedes Mal, wenn er mit der Ausführung von Offline-Code beginnt, sein "Offline" -Passwort zu übermitteln.
Rollen Sie nicht Ihre eigene Kryptographie - verwenden Sie eine bekannte Bibliothek wie die von Stanford zur Authentifizierung.
Nehmen Sie diesen Rat wie er ist . Wenden Sie sich an einen Sicherheitsexperten, bevor Sie diese Art der Authentifizierung in einer unternehmenskritischen Anwendung implementieren . Dies ist ein ernstes Problem, das sowohl schmerzhaft als auch leicht falsch zu verstehen ist.
Es ist wichtig, dass keine anderen Skripte Zugriff auf die Seite haben. Dies bedeutet, dass Sie nur externe Skripte mit Webworkern zulassen. Sie können keinen anderen externen Skripten vertrauen, die Ihr Kennwort abfangen könnten, wenn der Benutzer es eingibt.
Verwenden Sie ein prompt
und kein Inline-Kennwortfeld, wenn Sie sich nicht sicher sind und die Ausführung nicht verzögern (das heißt, es sollte nicht so lange funktionieren, bis Ereignisse darauf zugreifen können, sondern nur im Synchronisierungscode). Und speichern Sie das Kennwort nicht in einer Variablen. Dies funktioniert wiederum nur, wenn Sie darauf vertrauen, dass der Computer des Benutzers nicht gefährdet ist (obwohl dies auch für die Überprüfung gegen einen Server gilt).
Ich möchte noch einmal hinzufügen, dass wir dem Kunden immer noch nicht vertrauen . Sie können dem Kunden nicht alleine vertrauen, und ich denke, Joachim's Antwort nagelt es. Wir haben nur den Vorteil gewonnen, dass wir den Server nicht pingen müssen, bevor wir mit der Arbeit beginnen.
Zugehöriges Material: