Clientseitige Codierung: Wie kann eine böswillige Verwendung verhindert werden?

60

In den letzten Jahren hat der Trend für clientseitige (Browser-) Anwendungen deutlich zugenommen.

Für mein letztes Projekt habe ich mich entschieden, mit der Zeit zu gehen und eine clientseitige Anwendung zu schreiben.

Ein Teil dieser Anwendung umfasst das Senden von Transaktions-E-Mails an Benutzer (z. B. E-Mails zur Bestätigung der Anmeldung, zum Zurücksetzen des Kennworts usw.). Ich verwende eine Drittanbieter-API, um die E-Mails zu senden.

Normalerweise würde ich meine Anwendung auf einem Server laufen lassen. Ich würde die Drittanbieter-API aus dem Code auf meinem Server aufrufen.

Wenn Sie eine clientseitige Anwendung ausführen, muss dies jetzt im Browser eines Benutzers geschehen. Die Drittanbieter-API stellt die erforderlichen JavaScript-Dateien zur Verfügung, um dies zu erreichen.

Das erste eklatante Problem, das ich sehen kann, ist, dass ich einen API-Schlüssel verwenden muss. Dies wird normalerweise sicher auf meinem Server gespeichert, aber vermutlich muss ich jetzt diesen Schlüssel für den Client-Browser bereitstellen.

Angenommen, ich kann dieses Problem umgehen. Das nächste Problem ist, dass ein technisch versierter Benutzer das JavaScript-Entwicklertool in einem Browser nicht mehr lädt und die E-Mail-API trotzdem verwendet, anstatt zu sagen, dass er sich an Regeln hält, die ich in der Anwendung festgelegt habe .

Ich schätze, meine allgemeine Frage lautet: Wie können wir die böswillige Verwendung einer clientseitigen Anwendung verhindern?

Gaz_Edge
quelle
24
Haben Sie einen Grund, warum diese App nicht mit Ihrem eigenen Server kommuniziert und diese Anforderungen dann an den externen Dienst weiterleitet, den Sie benötigen? (Viele solcher
dienste
11
Aus diesem Grund sind API-Schlüssel letztendlich sinnlos. Der Server sollte nicht versuchen, der App zu vertrauen, die die Befehle sendet. es sollte nur dem Benutzer vertrauen.
Kevin Panko
42
Ich habe noch nie eine vernünftige Person gesehen, die "clientseitige Anwendung" als "unter keinen Umständen jemals mit einem Server kommunizieren" definiert hat - das scheint eher ein Strohmann als ein vernünftiges Argument zu sein. Natürlich gibt es einige Dinge, die Sie auf der Serverseite erledigen müssen, aber die meisten Aktionen können problemlos vor Ort ausgeführt werden, was wiederum die Reaktionsfähigkeit und Skalierbarkeit erheblich verbessert.
Voo
4
Wo sehen Sie eine Tendenz zu "Nur-Browser-Apps"? Ich habe noch nie etwas Ähnliches gesehen, was Sie beschreiben, Geheimnisse im Client-Code in einer wahnsinnig schlechten Idee aufzubewahren, selbst die eingefleischten Front-End-Leute, die ich kenne, würden das niemals tun.
Wheeyls
2
Jeder Versuch, sichere Ressourcen clientseitig zu schützen, ist zum Scheitern verurteilt, da er gegen mehrere der unveränderlichen Sicherheitsgesetze verstößt. # 2/3 - Wenn Ihre Software auf dem Computer Ihres Gegners ausgeführt wird, ist dies definitionsgemäß nicht Ihr Computer, und Sie haben bereits verloren. # 7 Der Versuch, eine Ressource durch Verschlüsselung zu schützen, ist zum Scheitern verurteilt, da Sie dem Client auch den Entschlüsselungsschlüssel bereitstellen müssen. # 10 Keine Technologie kann das oben genannte Problem beheben. blogs.technet.com/b/rhalbheer/archive/2011/06/16/…
Dan Neely

Antworten:

200

Sie können nicht und je mehr Menschen dies verstehen und je tiefer sie es verstehen, desto besser für die Welt.

Code, der auf einem Gerät ausgeführt wird, das vom Benutzer gesteuert wird, kann nicht gesteuert werden. Smartphones können einen Jailbreak erleiden. Set-Top-Boxen können geknackt werden. Gewöhnliche Browser versuchen nicht einmal, den Zugriff auf JavaScript-Code zu verhindern. Wenn Sie etwas wert zu stehlen oder zu missbrauchen, einen entschlossenen Angreifer wird der Lage sein , das zu tun, es sei denn Sie alles bestätigen Sie serverseitige schätzen.

Die Verschleierung hilft nur wenig. Die Art von Gegner, die Sie anziehen werden, sobald etwas entfernt Finanzielles involviert ist, liest Assemblersprache wie Kleinanzeigen. Die Verschlüsselung kann Ihnen nicht helfen, da das Gerät, das den Schlüssel schützen würde, dasselbe Gerät ist, von dem Sie annehmen müssen, dass es geknackt ist. Es gibt viele andere scheinbar offensichtliche Gegenmaßnahmen, die aus ähnlichen Gründen nicht funktionieren.

Leider ist dies eine sehr unbequeme Wahrheit. Die Welt ist voll von kleinen und großen Betreibern, die glauben, sie könnten die fundamentale Zerbrechlichkeit von Fernvertrauen irgendwie umgehen, einfach weil es so schön wäre, wenn wir davon ausgehen könnten, dass unser Code so ausgeführt wird, wie wir es angenommen haben. Und ja, es würde alles so viel einfacher machen, dass es nicht einmal lustig ist. Aber wenn Sie es nicht schaffen, können Sie sich und Ihre Kunden nur verbrennen, wenn Sie gegen die Hoffnung sind, dass Sie der einzige clevere Keks sind, der die Unannehmlichkeiten vermeiden kann. Stellen Sie sich daher vor, dass das Internet ein feindliches Gebiet ist, und berücksichtigen Sie die zusätzlichen Kosten in Ihren Schätzungen.

Das heißt, natürlich gibt es so etwas wie eine Tiefenverteidigung. Die Verschleierung Ihres JavaScript schreckt einen entschlossenen Angreifer nicht ab, kann jedoch einige weniger entschlossene Angreifer abschrecken. Wenn Ihr Vermögen einen ausreichenden Wert zum Schutz aufweist, jedoch nicht um jeden Preis, kann eine dieser Maßnahmen Ihrem System einen geschäftlichen Mehrwert verleihen. es kann einfach nicht perfekt sein. Solange Sie sich des Kompromisses, den Sie eingehen, voll bewusst sind, kann dies eine vernünftige Strategie sein.

Kilian Foth
quelle
6
Aber um das in die richtige Perspektive zu rücken: Dies gilt für JEDE Software, sei es ein Betriebssystem oder eine Transaktion. Am Ende gibt es einige sehr gute Code-Verschleierer, und Sie können die Messlatte höchstwahrscheinlich hoch genug legen, wenn es keinen unmittelbaren finanziellen Anreiz zum Hacken Ihrer Software gibt!
Falco
5
In diesen Tagen haben Unternehmen rechtliche Schritte eingeleitet, um gegen Personen vorzugehen, die den von ihnen erhaltenen Inhalt vor der Verarbeitung hacken (z. B. über Werbeblocker). Das zeigt nur, wie unmöglich technisches Handeln ist.
Kilian Foth
62
Wenn ich auf die ersten beiden Sätze näher eingehen darf, vermissen die subtilen Leute oft, dass es bei clientseitigen Browser-Apps darum geht, das Heben von Lasten abzuladen. Ihr Server ist weiterhin für vertrauenswürdige Vorgänge wie das Senden von E-Mails oder den Zugriff auf die Daten verantwortlich. Das Rendern eines Diagramms aus diesen Daten durch den Client spart jedoch CPU-Zeit (und Geld), ohne das Sicherheitsmodell zu ändern.
SSUBE
11
@Gaz_Edge Es ist wichtig zu beachten, dass das Problem hier nicht darin besteht, dass clientseitige Apps von Natur aus unsicher sind. Das Problem besteht darin, diese clientseitigen Apps so zu schreiben, dass dem Client Informationen anvertraut werden müssen, die nicht öffentlich sein sollen. Es ist durchaus möglich, eine clientlastige Anwendung zu schreiben, die genauso sicher ist wie eine Anwendung, bei der der größte Teil der Verarbeitung auf dem Server stattfindet. (Weitere Informationen hierzu finden Sie in der Antwort von jhocking. )
Ajedi32
7
@ Ajedi32 Clientseitige Apps sind unsicher. Es ist unmöglich, eine sichere App zu entwerfen, wenn eine auf Client-Seite durchgeführte Logik nicht auf Server-Seite überprüft wird. An diesem Punkt wird die clientseitige Logik zu einer Benutzeroberfläche oder zu einer Möglichkeit, grundlegende Überprüfungen auszulagern, aber alles muss immer auf dem Server überprüft werden !! .
69

Die Regel hier ist:

Tun Sie alles auf der Client-Seite, was niemanden betrifft, wenn der Benutzer daran herumfummelt. Dies bedeutet insbesondere grafische Effekte.

Tun Sie alles, was serverseitig sicher sein muss, und senden Sie einfach UI-Ereignisse vom Client (z. B. sagt der Client nur "der Benutzer hat auf die Schaltfläche" Kaufen "geklickt", während der Server die Transaktion tatsächlich ausführt). Dies bedeutet insbesondere finanzielle Transaktionen.

schockierend
quelle
28

Dies ist genau der Fall, wenn eine vollständig clientseitige Anwendung nicht geeignet ist.

Sie können die Logik und grundlegende Validierung von Formularen clientseitig vornehmen (auf dem Server muss noch eine erneute Validierung durchgeführt werden, da möglicherweise jemand versucht, die Anforderung zu fälschen), um die Reaktionsfähigkeit zu verbessern. Sie können HTTP-Anforderungen von JavaScript ausführen, um Daten in JSON hin und zurück zu übergeben Vermeiden Sie das erneute Senden von Seitendekorationen und dergleichen. Wenn die Transaktion selbst authentifiziert und autorisiert werden muss, sollte dies dennoch auf einem Server geschehen.

Jan Hudec
quelle
11
Hinweis: Während es großartig ist, Formulare clientseitig zu validieren, vergessen Sie niemals, sie auch serverseitig zu validieren! Wenn Sie Ihren Client-Code an den Browser senden, wird er nicht mehr Ihr Code! Sie müssen jedes einzelne gesendete Bit erneut validieren!
Josef
17

Ihr mittlerer Absatz ist das Herzstück des Problems:

Wenn Sie eine clientseitige App ausführen, muss dies jetzt im Browser eines Benutzers geschehen. Die Drittanbieter-API stellt die erforderlichen js-Dateien zur Verfügung, um dies zu erreichen.

Warum bedeutet eine clientseitige App, dass Sie nicht serverseitig arbeiten können? Der Vorstoß zur clientseitigen Programmierung besteht nicht darin, Server zu eliminieren, sondern neuere Technologien zu nutzen, die von Browsern unterstützt werden, um bessere Benutzeroberflächen zu schaffen.

Sind .jsSie sicher, dass die erhaltene Datei für einen Browser bestimmt ist? Könnte es eine node.js Bibliothek sein?

Brandon
quelle
4
+1 für den wirklich guten Vorschlag, dass die JS-Datei für einen NodeJS-Server vorgesehen ist
Machinarius
11

Lassen Sie uns einen Schritt zurücktreten und einen Blick auf eine höhere Ebene werfen. Sollten wir. Hat Eudora oder Outlook (eine clientseitige App, die nicht einmal einen Browser benötigt) jemals einen finanziellen Verlust für ein Unternehmen verursacht? Nein. Jeder kann auf die POP / SMTP-APIs schreiben und der Client sein. Aber kein Verlust für den Server. Der Server hat Clientaktionen, Berechnungen, Speicher, Temperatur, Festplattengröße, RAM-Größe, Monitor-DPI, GPU, FPU-Yada-Yada des Clients nicht beschränkt, sondern genau angegeben, worauf er antworten würde, und nicht mehr. Haben Sie jemals davon gehört, dass mit Quicken oder MS-Money eine Bank aufgebrochen wird?

Ihre Browser-App (dh clientseitige App) kann dieselbe Architektur verwenden.

  1. Sie erstellen Ihren Server mit einer API (die sich übrigens immer auf Derivate von GET POST HEAD usw. beschränkt).
  2. Stellen Sie auf dem Server sicher, dass die API bei jedem Aufruf nur mit einem authentifizierten und identitätsverifizierten Client kommuniziert.
  3. Dann ist es dir egal, wer der Kunde ist.
  4. Und dann ist es dir egal, ob es sich um einen Browser, ein Gerät mit Jailbreak, Google Glass, DOS 3.1 oder ein brandneues Nexus in den Händen eines technophoben Ur-Ur-Ur-Ur-Opas handelt, der schon 2014 gereist ist und alles verpasst hat Die Technologie, die in den letzten 15 Jahrzehnten unser Leben überschwemmt hat.
  5. Jetzt können Sie anfangen, alles andere auf die Client-Seite zu laden.

SoapBoxBegin

@KilianFoth wirft ein wichtiges Problembewusstsein für die Naiven und Leichtsinnigen auf, vor allem für diejenigen, die die Schlagzeilen ständig lesen, aber niemals glauben, dass dies mit ihrer App, ihrem Code, ihrem Arbeitgeber, ihrem Kunden oder ihrem eigenen Bankkonto passieren wird. Noch rücksichtsloser sind ihre Arbeitgeber (insbesondere die CTOs), die es Apps erlauben würden, herauszukommen, um Systeme einer nicht verwalteten / unkontrollierten Gefährdung auszusetzen. Ich bin jedoch immer verwirrt darüber, wie es scheint, dass "wir nie lernen".

SoapBoxEnd

Also, um es zusammenzufassen. Erstellen Sie eine solide und enge serverseitige API. Laden Sie alles andere auf den Client herunter, je nachdem, was der Client verarbeiten kann.

LMSingh
quelle
6

Ich würde argumentieren, dass Sie wirklich nicht können. Wenn Sie bereit sind, die Daten an den Kunden zu senden, müssen Sie damit rechnen, dass sie missbraucht werden - wie auch immer möglich. Ihr Beispiel in Bezug auf den API-Schlüssel veranschaulicht den Punkt, und ich würde das nicht in Ihre clientseitige JS aufnehmen - es wird gestohlen und missbraucht.

Sie benötigen auf jeden Fall noch eine gewisse Menge an Servercode, um die Sicherheit zu gewährleisten. Sogar etwas so Einfaches wie das Abrufen nur der Daten, die sich auf den angemeldeten Benutzer beziehen. Diese Authentifizierung kann nicht alle clientseitig durchgeführt werden. Andernfalls werden Sie ausgenutzt und Ihre Daten sind nicht sicher.

Ich würde die Erfahrung auf der JS-Clientseite immer als Ergänzung zum Servercode betrachten. Die Überprüfung auf dem Client bietet eine angenehme Benutzererfahrung. Wenn Sie jedoch nicht überprüfen, ob die POST-Daten auch auf dem empfangenden Server vorhanden sind, können Sie angreifen. Alles vom Kunden sollte als verdächtig angesehen werden.

Matt Klinker
quelle
4

Es ist wirklich ganz einfach. Angenommen, der Client-Computer und die gesamte darauf ausgeführte Software stehen unter der vollständigen Kontrolle eines cleveren böswilligen Hackers.

Das bedeutet, dass alle Informationen, die Sie vom Server an den Client senden, dem böswilligen Hacker bekannt sind. Sie müssen also sicherstellen, dass Sie keine Informationen an den Client senden, die dazu verwendet werden könnten, Ihren Server oder Ihr Unternehmen anzugreifen.

Dies bedeutet auch, dass alles, was vom Client an den Server gesendet wird, vom böswilligen Hacker erstellt wurde. Daher muss Ihr Servercode sicherstellen, dass nichts, was der Client senden kann, Ihren Server erfolgreich angreifen kann.

Zugegeben, die Implementierung ist ein Problem, aber das Wichtigste ist die mentale Einstellung, die Annahme, dass der "Client", mit dem Sie Ihren Server ansprechen, kein Client, sondern ein aktiver Angreifer ist.

(Sie müssen auch davon ausgehen, dass der Benutzer ein cleverer Betrüger ist, der versucht, Ihre Geschäftsmethoden anzugreifen, was jedoch nichts mit clientseitiger Programmierung zu tun hat.)

gnasher729
quelle
0

Bei der clientseitigen Anwendung geht es meiner Meinung nach hauptsächlich um die Benutzeroberfläche. Zum Beispiel wird Ihr gesamtes UI-System einmal an den Client gesendet, und der Client würde dann tun, was er will.

Normalerweise würde ich meine Anwendung auf einem Server laufen lassen. Ich würde die Drittanbieter-API aus dem Code auf meinem Server aufrufen.

Wenn Sie eine clientseitige Anwendung ausführen, muss dies jetzt im Browser eines Benutzers geschehen. Die Drittanbieter-API stellt die erforderlichen JavaScript-Dateien zur Verfügung, um dies zu erreichen.

Wenn Sie einen API-Schlüssel haben, ist es nicht beabsichtigt, auf der Clientseite zu arbeiten. Wenn Sie den API-Schlüssel auf der Clientseite angeben, hat jeder Zugriff darauf und kann ihn dann für eigene Zwecke verwenden. Speichern Sie es und verwenden Sie es serverseitig, wenn der Client es benötigt. Senden Sie dann das Ergebnis mit Ajax / WebSockets.

Es ist, als würde Ihre Bank sagen: "Nun, ich werde das Kennwort des Hauptdatenbank-Clients eingeben, damit der Client es selbst anfordern kann, und er wird unsere Server nicht mehr stören."

Depado
quelle