Gibt es einen Grund, nicht direkt von clientseitigem Javascript in eine Datenbank zu wechseln?


62

Mögliches Duplikat:
Schreiben von "serverlosen" Webanwendungen

Nehmen wir also an, ich werde einen Stack Exchange-Klon erstellen und beschließe, so etwas wie CouchDB als Backend-Speicher zu verwenden. Wenn ich deren integrierte Authentifizierung und Autorisierung auf Datenbankebene verwende, gibt es einen Grund, das clientseitige Javascript nicht direkt auf den öffentlich verfügbaren CouchDB-Server schreiben zu lassen? Da es sich im Grunde genommen um eine CRUD-Anwendung handelt und die Geschäftslogik aus "Nur der Autor kann seinen Beitrag bearbeiten" besteht, sehe ich keine große Notwendigkeit, eine Schicht zwischen dem clientseitigen Material und der Datenbank zu haben. Ich würde einfach die Validierung auf der CouchDB-Seite verwenden, um sicherzustellen, dass niemand Garbage-Daten einfügt, und um sicherzustellen, dass die Berechtigungen richtig festgelegt sind, sodass Benutzer nur ihre eigenen _user-Daten lesen können. Das Rendern würde clientseitig von AngularJS durchgeführt. Im Grunde könnten Sie nur einen CouchDB-Server und ein paar "statische" Seiten haben und schon kann es losgehen. Sie würden keine serverseitige Verarbeitung benötigen, nur etwas, das die HTML-Seiten bedienen könnte.

Das Öffnen meiner Datenbank für die Welt scheint falsch, aber in diesem Szenario kann ich mir nicht vorstellen, warum, solange die Berechtigungen richtig festgelegt sind. Das widerspricht meinem Instinkt als Webentwickler, aber mir fällt kein guter Grund ein. Warum ist das eine schlechte Idee?

BEARBEITEN: Sieht so aus, als gäbe es hier eine ähnliche Diskussion: Schreiben von Anwendungen ohne Webserver

EDIT: Tolle Diskussion bisher, und ich freue mich über das Feedback aller! Ich denke, ich sollte ein paar allgemeine Annahmen hinzufügen, anstatt CouchDB und AngularJS speziell aufzurufen. Nehmen wir also an, dass:

  • Die Datenbank kann Benutzer direkt aus ihrem versteckten Speicher authentifizieren
  • Die gesamte Datenbankkommunikation würde über SSL erfolgen
  • Die Datenvalidierung kann (sollte aber vielleicht nicht?) Von der Datenbank übernommen werden
  • Die einzige Berechtigung, die wir für andere als die Admin-Funktionen haben, ist, dass nur jemand seinen eigenen Beitrag bearbeiten darf
  • Wir sind vollkommen in Ordnung, wenn jeder in der Lage ist, alle Daten zu lesen (AUSSER Benutzerdatensätze, die Passwort-Hashes enthalten können).
  • Administrative Funktionen würden durch die Datenbankautorisierung eingeschränkt
  • Niemand kann sich einer Administratorrolle hinzufügen
  • Die Datenbank ist relativ einfach zu skalieren
  • Es gibt wenig bis gar keine echte Geschäftslogik. Dies ist eine grundlegende CRUD-App

Nicht gerade reine "Client-Seite zur Datenbank", aber haben Sie sich Parse und Firebase angesehen? (und bis zu einem gewissen Grad auch Meteor), alle haben relevante Konzepte und gehen kreativ mit Sicherheit um. siehe zB
Eran Medan

Ja! Ich hatte zuvor schon von Parse gehört, aber nicht von Firebase. Sehr interessant und definitiv in der Art, wie ich es mir vorgestellt habe.
Chris Smith

Wie würde Ihre Datenbank vor dem Versenden von SQL-Injection oder XSS aus JavaScript schützen? So ziemlich alles, was vom Client gesendet wird, muss als unsicher eingestuft werden. Welche Bestimmungen in dieser Datenbank können Sie zum Filtern der Daten verwenden, um sicherzustellen, dass sie gültig sind, und um Daten mit vorbereiteten Anweisungen einzufügen?
zuallauz

6
Wenn Sie alles andere ignorieren, erstellen Sie eine zweistufige Anwendung, die Ihre Benutzeroberfläche eng mit der Datenbank verbindet. Keine wirklich gute Idee, es sei denn, Ihre App ist trivial.
Andy

12
SSL wird nicht verhindern, dass jemand ausgeführt wirdDELETE FROM ImportantData;
user253751

Antworten:


48

Wenn Sie so tun, wie Sie es vorschlagen, wird eine enge Verbindung zwischen Ihrer clientseitigen Sprache und Ihrer Datenbank hergestellt.

Das kann in Ordnung sein - es muss weniger Code geschrieben und gewartet werden, und theoretisch könnte / sollte das Debuggen etwas schneller gehen.

Andererseits erschwert es andere Aspekte. Wenn Sie eine dieser Technologien ändern müssen, fällt es Ihnen aufgrund der engen Kopplung schwerer.

Sich vor Angriffen zu schützen, wird (ziemlich) schwieriger. Sie gehen davon aus, dass der Client der Datenbank immer gut formatierte Anforderungen bereitstellt. Das setzt voraus, dass niemand jemals den clientseitigen Code hacken wird, um böswillige Anweisungen einzufügen. Mit anderen Worten, sie "leihen" Ihre Authentifizierungsmechanismen aus und ersetzen den normalen Client-Code durch ihren.

Ich würde es nicht empfehlen, und viele würden Ihnen vehement raten, es nicht zu tun. Aber es kann getan werden.


Interessant. Wie kann ein Angreifer meinen Authentifizierungsmechanismus ausleihen? Ich würde dem Kunden nicht vertrauen, sich zu authentifizieren. Die Datenbank würde einfach einen HTTPS-POST an den Sitzungsendpunkt senden, der das POST-Kennwort enthält, und prüfen, ob es gültig ist. Wenn dies der Fall ist, wird ein Sitzungscookie zurückgegeben, der für zukünftige Anforderungen verwendet wird.
Chris Smith

1
Ich brauche nur den Session-Cookie, oder? Ich benutze Ihren Client, um meinen Session-Cookie zu erstellen und abzurufen. Dann klaue ich den Sitzungscookie mit meinem Kunden und sende schlecht formatierte Anfragen, um Chaos zu verursachen. Denken Sie daran, dass sich alles auf meinem Computer befindet, sodass ich nicht einmal einen MiTM-Angriff benötige.

7
@ChrisSmith - Solange Sie das Gefühl haben, die Sicherheitsbedenken auszuräumen, behandeln Sie den primären Einwand gegen das, was Sie vorgeschlagen haben. Wenn Sie sie in den Griff bekommen oder glauben, dass Sie es tun, dann versuchen Sie es. Die einfache Version Ihrer Frage lautet: Sie haben gefragt, warum die Leute kein ABC machen. Die primäre Antwort ist Sicherheit und enge Kopplung. Beheben Sie diese Bedenken und entfernen Sie den Code.

2
Ganz zu schweigen davon, dass Sie nicht über einen Ort verfügen, an dem häufig angeforderte Daten zwischengespeichert werden können, sodass Sie jedes Mal die Datenbank aufrufen müssen. Sicher, vielleicht führt Ihr DB-Treiber eine Zwischenspeicherung durch, aber wie einstellbar ist das? Wird es über Threads hinweg geteilt?
TMN

1
Es ist mir unangenehm, direkten Zugriff auf meine SQL-Datenbanken über direkte SQL-Anweisungen von Web-Clients zuzulassen, da Sie nie wissen, welche Art von Anforderungen sie stellen werden. Werden sie Anweisungen zum Löschen, Aktualisieren oder Einfügen ausführen? Wenn ja, werden sie die von Ihrer Anwendung erwarteten Daten bereitstellen? Werden unerwartete Löschungen auftreten? Unerwartete Datenbankänderungen führen normalerweise zu einem Absturz Ihrer Anwendung. Am besten minimieren Sie die Befehle, die an Ihre Datenbank gesendet werden, damit Sie die eingegangenen Eingaben einfacher bereinigen können, damit Ihre Anwendung besser funktioniert.
Nathan Pilling

36

Das ist wahrscheinlich keine gute Idee. Und der erste und stärkste Grund , den ich geben kann , ist , dass ein Datenbankserver ist nicht entworfen öffentliche Web - Server zu sein. Im Gegenteil, konventionelle Weisheit besagt, dass Sie Ihre Datenbank hinter einer Firewall verstecken sollten.

Wenn Sie Nachweise benötigen, gibt es viele Bedenken - nicht alle unüberwindlich, aber viele, über die Sie nachdenken müssen. In keiner bestimmten Reihenfolge sind hier einige:

  • Die Abfragebereinigung kann nicht durchgeführt werden, da die Abfragen direkt gesendet werden.
  • Datenbankberechtigungen funktionieren normalerweise anders als Webserver- und Anwendungsberechtigungen. Mit Webservern und Anwendungsframeworks haben Sie nichts zu tun, und Sie müssen einzelne Ressourcen, Endpunkte und Aktionen explizit erstellen und verfügbar machen. Datenbanken fordern Sie dagegen auf, Rollen auf hoher Ebene zuzuweisen.
  • Es ist wahrscheinlich nicht gut optimiert, um die Arbeitslast eines Webservers aufrechtzuerhalten. Sie können nicht vom Verbindungspooling profitieren.
  • Die populäreren Webserver sind in eine Menge aufgeteilt worden . Und sie haben viele Sicherheitspatches erhalten. Ihr DBMS wurde im Grunde so konzipiert, dass es sich hinter einer Firewall verbirgt. Daher wurde es wahrscheinlich nicht einmal von einem Bruchteil der potenziellen Bedrohungen getestet, denen es im öffentlichen Web ausgesetzt sein wird.
  • Sie müssen die Abfragesprache der Datenbank verwenden, um private Daten zu schützen. Abhängig von Ihrem DBMS kann dies eine Herausforderung sein.
  • Sie müssen die Abfragesprache der Datenbank verwenden, um große Datenmengen zu filtern. Möglicherweise möchten Sie dies trotzdem tun. aber etwas, das für kompliziertere Geschäftsregeln lästig werden kann.
  • Eingeschränkte oder keine Unterstützung für Bibliotheken von Drittanbietern.
  • Sehr begrenzter Community-Support (möglicherweise null) für viele der Probleme, auf die Sie stoßen.

... und ich bin sicher, dass es noch andere Bedenken gibt. Und ich bin sicher, dass es für die meisten Probleme eine Lösung gibt - wenn nicht für alle. Aber es gibt eine Liste, mit der Sie loslegen können!


1
Hier gibt es einige gute Denkanstöße. Nicht alle diese Punkte werden in jeder Situation zutreffen und werden gleich wichtig sein, aber es ist großartig, eine prägnante Aufzählungsliste zu haben, die die Gänge zeigt. Vielen Dank!
Dav,

16

Der beste Grund, den ich mir vorstellen kann, ist, dass diese Methode von keiner beteiligten Partei direkt unterstützt oder empfohlen wird.

Browserhersteller, EcmaScript-Standards, Entwickler von Datenbanksystemen, Netzwerkausrüstungsunternehmen, Hosting- / Infrastrukturarchitekten und Sicherheitsspezialisten unterstützen Ihren vorgeschlagenen Anwendungsfall nicht aktiv (oder berücksichtigen ihn möglicherweise sogar). Dies ist ein Problem, da Ihre vorgeschlagene Methode erfordert, dass alle diese Entitäten und mehr für Ihre Anwendung geeignet sind, auch wenn keines der beteiligten Systeme dafür ausgelegt ist.

Ich sage nicht, dass es nicht möglich ist. Ich sage nur, das ist weniger so, als würde man das Rad neu erfinden, als vielmehr die browserbasierte Client-Server-Interaktion.

Im besten Fall werden Sie eine Menge Arbeit leisten, um die Systeme auf das grundlegendste Niveau zu bringen. Moderne, weit verbreitete Datenbanken sind nicht REST-fähig oder für die Arbeit über HTTP ausgelegt. Sie erstellen daher Ihre eigenen WebSocket-basierten Client-Treiber (ich nehme an).

Selbst wenn Sie alles technisch zum Laufen bringen, werden Sie viele der leistungsfähigsten Merkmale moderner Architekturen aufgeben. Sie haben keine Tiefenverteidigung - jeder kann sich problemlos direkt mit dem Hauptziel der meisten Website-Hacking-Versuche verbinden. Aber das von Ihnen vorgeschlagene Szenario ist viel, viel schlimmer.

Das vorgeschlagene Modell macht nicht nur den Server verfügbar, sondern auch gültige Verbindungszeichenfolgen. Angreifer können nicht nur den Server anpingen, sondern sich auch aktiv anmelden und ihm Befehle geben. Selbst wenn Sie den Datenzugriff einschränken können, sind mir nicht genügend Tools in DBMS-Systemen bekannt, um vor Denial-of-Service-Szenarien und deren Folgen zu schützen. Wenn Sie mit erweiterten SQL-Versionen wie TSQL arbeiten, ist es oftmals trivial einfach, Bomben zu produzieren, die effektiv unendlich laufen. . Ich würde mir vorstellen, Sie müssten die meisten Funktionen von SQL deaktivieren, sogar grundlegende SELECT-Abfragen mit JOINs eliminieren und möglicherweise nur das Aufrufen gespeicherter Prozeduren zulassen. Ich weiß nicht einmal, ob Sie das können, ich wurde nie gebeten, es zu versuchen. Tut es nicht'

Die Skalierbarkeit von Datenbanken ist auch eines der schwierigsten Probleme bei der Arbeit in großem Maßstab, während das Skalieren mehrerer HTTP-Server - insbesondere bei statischen oder zwischengespeicherten Seiten - eines der einfachsten Probleme ist. Ihr Vorschlag bewirkt, dass die Datenbank mehr Arbeit leistet, da sie für 100% der serverseitigen Aktivitäten verantwortlich ist. Das ist von sich aus ein Mörderfehler. Was Sie durch die Verlagerung der Arbeit auf den Client gewinnen, verlieren Sie, wenn Sie mehr Arbeit in die Datenbank verlagern.

Abschließend möchte ich nur darauf hinweisen, dass das Herz Ihrer Vorschläge nicht neu ist, sondern Jahrzehnte zurückreicht. Dieses Modell wird als "Fat Database" -Modell bezeichnet, bei dem die meiste serverseitige Logik genau so in die Datenbank verschoben wurde, wie Sie es vorgeschlagen haben. Es gibt viele Gründe, warum das Modell im Massen-Internet auf der Strecke geblieben ist, und es wäre wahrscheinlich informativ, selbst mehr über diese Geschichte zu erfahren. Beachten Sie auch, dass selbst dann kaum in Betracht gezogen wurde, dass sich nicht vertrauenswürdige Benutzer am System anmelden und Befehle ausführen können, da der Zugriff weiterhin kontrolliert wird, um interne (bekannte) Benutzer auszuwählen, die das System nicht ständig angreifen sollten.

Tatsache ist, dass Sie immer noch einen HTTP-Server benötigen, um Dateien bereitzustellen, da Datenbanksysteme dies einfach nicht tun. Gleichzeitig kann alles, was Sie vorschlagen, mithilfe eines Thin-Server-Modells (z. B. mit Nodejs) abgerufen werden, um eine RESTful-Schnittstelle für Ihre Datenbank bereitzustellen. Dies ist aus einem bestimmten Grund beliebt - es funktioniert, verbirgt die Datenbank hinter Schutzebenen, ist extrem skalierbar und ermöglicht es Ihnen dennoch, Ihre Datenbank so dick oder so dünn aufzubauen, wie Sie möchten.


8

Da es sich im Grunde genommen um eine CRUD-Anwendung handelt und die Geschäftslogik aus "Nur der Autor kann seinen Beitrag bearbeiten" besteht, sehe ich keine große Notwendigkeit, eine Schicht zwischen dem clientseitigen Material und der Datenbank zu haben. Ich würde einfach die Validierung auf der CouchDB-Seite verwenden, um sicherzustellen, dass niemand Garbage-Daten einfügt, und um sicherzustellen, dass die Berechtigungen richtig festgelegt sind, sodass Benutzer nur ihre eigenen _user-Daten lesen können.

Wenn Sie Ihre Berechtigung (die Sicherheitsbedenken) und die Logiküberprüfung von der Datenbank entfernen, werden die Bedenken in Ihrem Softwaresystem getrennt. Auf diese Weise können Sie Ihre logischen Codeblöcke testen, warten, skalieren und wiederverwenden, wobei das Risiko geringer ist, dass die Funktionalität des Systems beeinträchtigt wird.

Die Möglichkeit zur direkten Kommunikation mit der Datenbank über Client-Eingaben birgt ein großes Potenzial, die Daten zu vermasseln .

Dies bedeutet auch, dass das Vermeiden / Entfernen einer engen Kopplung Ihr Softwaresystem wartungsfreundlicher und SOLID macht.


1
Normalerweise würde ich dem zustimmen, aber ich kann Codeblöcke innerhalb des clientseitigen Codes genauso einfach wie serverseitig testen, warten und skalieren. Alles in Javascript zu tun, wäre keine Entschuldigung dafür, die Bedenken nicht richtig zu trennen. Ich verschiebe einfach die eigentliche Verarbeitung vom Server auf den Client. Also, was ist mit der Schicht zwischen mir zu kaufen?
Chris Smith

2
Die clientseitige Validierung ist für den Client von Vorteil, auf der Serverseite ist sie jedoch wichtiger als je zuvor. Weil Ihre clientseitige Anfrage einfach simuliert werden kann. Logische Trennungen und / oder Ebenen tragen zur Geselligkeit und Wartbarkeit bei.
EL Yusubov

Also, ich spiele Devil's Advocate: Wie ich unten erwähnte, könnte ich die Validierungsfunktionen von CouchDB verwenden, um festzustellen, ob die übermittelten Daten gültig sind. Wenn Sie versuchen, ein Dokument hinzuzufügen oder zu aktualisieren, wird überprüft, ob dies zulässig und korrekt formatiert ist. Es bringt mehr Verarbeitung auf die Datenbankseite, aber es ist ziemlich leicht und ich muss trotzdem überlegen, die Datenseite zu skalieren. Würde dies nicht das Anliegen ansprechen?
Chris Smith

Nein, das glaube ich nicht. Das Platzieren Ihrer Validierungs- und Autorisierungslogik in der Datenbank wird die Leistung Ihres Systems beeinträchtigen, sobald die Anzahl der Datensätze steigt und Sie mehr Benutzer auf Ihrem System haben.
EL Yusubov

Die DB-Engines sollen die Daten speichern und abrufen, nicht manipulieren oder validieren. Natürlich können Sie es auf Ihre Weise tun, aber es ist nicht der effiziente Weg, um zu folgen.
EL Yusubov

6

Es scheint mir wirklich gefährlich, den Benutzer direkt mit der Datenbank interagieren zu lassen.

Ist der Authentifizierungsmechanismus von CouchDB wirklich so ausgefeilt, dass Sie den Lese- und Schreibzugriff eines Benutzers nur auf die Daten beschränken können, die er lesen und schreiben soll (es handelt sich um den Zugriff pro Dokument, möglicherweise sogar pro Dokument im Feld) Privilegien hier)? Was ist mit "kommunalen" Daten, die von mehreren Benutzern geteilt werden? Gibt es das in Ihrem Anwendungsdesign überhaupt nicht?

Möchten Sie wirklich, dass der Benutzer seine Daten auf JEDE Weise ändern kann? Was ist zum Beispiel mit XSS-Injektionen? Wäre es nicht besser, eine Serverebene zu haben, um diese zu filtern, bevor sie in die Datenbank gelangen?


1
Sie bringen gute Punkte vor, und ich dachte das Gleiche. Ich bin zu dem Schluss gekommen, dass ich in dieser (hypothetischen) Anwendung damit einverstanden bin, dass jeder etwas liest, AUSSER Benutzerdatensätze. Sie können nur in Dokumente schreiben, die sie ursprünglich erstellt haben (das ist die einzige "Geschäftslogik", die ich oben erwähnt habe). CouchDB scheint in der Lage zu sein, beides über die interne Benutzerdatenbank und Validierungsfunktionen zu tun.
Chris Smith

6

Sie haben eine Reihe von Gründen, aber noch einen: Zukunftssicherheit. Früher oder später, wenn sich Ihre Anwendung weiterentwickelt, werden Sie mit einigen Anforderungen konfrontiert, die in clientseitigem JS oder als gespeicherte Prozedur in Ihrer Datenbank nicht ohne weiteres oder sicher erreicht werden können.

Beispielsweise wird Ihnen mitgeteilt, dass für alle neuen Registrierungen eine CAPTCHA-Bestätigung erforderlich ist, um gültig zu sein. Dies wäre mit so ziemlich jedem modernen Webanwendungs-Framework wirklich einfach genug. Schlagen Sie einfach ein reCAPTCHA in das Registrierungsformular ein, übergeben Sie das Antwort-Token von reCAPTCHA an das Backend und fügen Sie Ihrem Backend ein paar Codezeilen hinzu, um die Gültigkeit des Tokens mit der API von Google zu überprüfen (oder besser noch, verwenden Sie eine Bibliothek, die jemand anderes dafür geschrieben hat) für dich).

Wenn Sie ein zweistufiges System verwenden und sich für Ihre gesamte serverseitige Logik auf die Datenbank verlassen, wie können Sie das Token überprüfen? Ja, ich nehme an, es könnte theoretisch möglich sein, abhängig vom DBMS eine gespeicherte Prozedur zu schreiben, die irgendwie eine Shell aufruft und curl mit den richtigen Argumenten aufruft. Das ist mit ziemlicher Sicherheit auch eine schreckliche Idee: Das Filtern von Eingaben und der Schutz vor Sicherheitslücken wären schrecklich. Sie hätten ein Durcheinander mit Fehlerbehandlung und Zeitüberschreitungen; und Sie müssten die Antwort selbst analysieren. Ganz zu schweigen davon, dass ein DBMS dies nicht tun soll. Es gibt also keinen Grund zu der Annahme, dass Leistung, Stabilität, Thread-Sicherheit usw. keine Probleme darstellen. Siehe zum Beispiel diesen Thread , in dem einige dieser Probleme für Postgres behandelt werden.

Und genau darum geht es, einem Formular ein einfaches CAPTCHA hinzuzufügen. Was können Sie tun, wenn Sie eine SMS-Bestätigung oder einen Hintergrundjob hinzufügen möchten, bei dem inaktive Benutzer per E-Mail an Ihre App erinnert werden, oder wenn Sie eine Funktion zum Hochladen von Dateien hinzufügen, damit Benutzer ein Profilbild festlegen können? Vielleicht entscheiden Sie, ob Ihre Anwendung eines Tages einige automatisierte Tests haben soll? Oder dass Sie Änderungen an Ihren Prozeduren in einem Versionskontrollsystem verfolgen möchten? Es gibt zahlreiche Bibliotheken und Tools für die meisten nützlichen Sprachen, um die meisten dieser Aufgaben für Sie zu erledigen. Für Ihr DBMS stehen jedoch nur wenige bis keine zur Verfügung, da dies nicht vorgesehen ist.

Schließlich möchten Sie etwas tun, das Sie vernünftigerweise nicht direkt in Ihrem DBMS tun können, und dann stecken Sie fest. Da Sie Ihre gesamte Anwendung in Ihrem DBMS erstellt haben, bleibt Ihnen keine andere Wahl, als sich einen Webserver zu besorgen und Teile in einer anderen Sprache neu zu erstellen, nur um eine einfache Funktion hinzuzufügen.

Und das wäre eine echte Schande, denn wir haben bereits einen Namen für den Ort, an dem Sie Ihre Anwendungslogik ablegen, und er wird aus einem bestimmten Grund "Quellcode Ihrer Anwendung" und nicht "gespeicherte Datenbankprozeduren" genannt.


5

Wenn Ihre Sicherheitsüberprüfungen und Geschäftslogik in Ihrem clientseitigen Javascript enthalten sind, können sie von einem böswilligen Benutzer überschrieben werden. Alternativ können Sie eine JavaScript-basierte serverseitige Technologie (wie Node.JS ) verwenden, um die Validierung, Autorisierung und dergleichen durchzuführen .


Die Authentifizierung und Autorisierung würde von der Datenbank selbst übernommen, sodass ich dem Client in dieser Hinsicht überhaupt nicht vertrauen würde. CouchDB verfügt über integrierte Validierungsfunktionen, die ausgelöst werden, wenn Sie versuchen, ein Dokument zu aktualisieren, sodass ich anhand dieser Funktionen überprüfen kann, ob die gesendeten Daten gültig sind.
Chris Smith

2

Alle geschäftlichen Einschränkungen, die Sie sicherstellen möchten, sollten serverseitig überprüft werden. Auch wenn Sie den Benutzerzugriff kontrollieren, kann jemand ungültige Daten senden.

Folgendes Beispiel für Ihren Stackoverflow-Klon:

  • Wie würden Sie verhindern, dass "geschlossene" Fragen auf der Website bearbeitet werden?
  • Wie würden Sie verhindern, dass Personen Kommentare löschen?
  • Wie würden Sie verhindern, dass Personen Kommentardaten vortäuschen?
  • Wie würden Sie verhindern, dass Personen 50-mal den gleichen Beitrag stimmen?
  • Es gibt wahrscheinlich viel mehr Beispiele, wenn Sie ein bisschen mehr graben.

Jeder kann den clientseitigen Code manipulieren und die Datenintegrität vollständig verletzen (selbst wenn er auf bestimmte Objekte beschränkt ist, wie z. B. seine eigenen Posts).


1

Bearbeite die Seite in Firebug und füge irgendwann eine Zeile ein, die der folgenden ähnelt:

ExecDbCommand("DROP TABLE Users")

Starte es.

Bearbeiten:

Die Frage war in der Tat über CounchDB, so dass hier kein SQL ausgeführt werden muss. Die Idee ist jedoch dieselbe. Ich würde annehmen, dass jede nicht triviale Anwendung von Daten abhängt, um einige Konsistenzregeln zu beachten, die vom Anwendungscode geprüft / durchgesetzt werden. Ein böswilliger Benutzer kann den Clientcode so ändern, dass Daten in einer Form gespeichert werden, die gegen Ihre Geschäftsregeln verstößt und in Ihrer Anwendung Chaos verursachen kann.

Wenn Ihre Site davon ausgeht, dass alle möglichen Datenzustände aus geschäftlicher Sicht gültig sind, gehen Sie auf jeden Fall diesen Weg. Ist dies jedoch nicht der Fall (wahrscheinlich), möchten Sie die Garantie haben, dass alle gespeicherten Daten von Ihnen generiert werden Code und nach Ihren Regeln .


CouchDB würde nicht wissen, was ich damit anfangen soll, aber ich verstehe, worum es geht. Wenn die Berechtigungen richtig eingestellt sind, ist die Antwort auf eine solche Angelegenheit ein 401 Unauthorized.
Chris Smith

-1, wenn Sie SQL-Code posten, wissen Sie offensichtlich nicht einmal, was CouchDB ist. Durch das Erstellen eines Administratorkontos auf CouchDB verhindern Sie außerdem bereits, dass ein anderer Benutzer die gefährlichsten Vorgänge ausführt.
Philipp

Fair genug. Ich übersprang den Teil auf CouchDB in der Frage und registrierte es nur als "Zugriff auf Datenspeicher von Client-Seite JS direkt". Ich bearbeite die Antwort.
AZ01

1
+1, SQL oder nicht, sein Punkt gilt immer noch. Ein JS-Debugger kann verwendet werden, um den Zugriff auf Daten zu ändern.
GrandmasterB

1

Alte Frage, ich weiß, aber ich wollte mitmachen, weil meine Erfahrung ganz anders ist als die der anderen Antworten.

Ich habe viele Jahre damit verbracht, Echtzeitanwendungen für die Zusammenarbeit zu schreiben. Der allgemeine Ansatz für diese Anwendungen besteht darin, Daten lokal zu replizieren und Änderungen so schnell wie möglich mit Kollegen zu synchronisieren. Alle Vorgänge an Daten sind lokal, sodass Datenspeicherung, Datenzugriff, Geschäftslogik und Benutzeroberfläche lokale Ebenen sind. Die "Offline First" -Bewegung ( http://offlinefirst.org/ ) hat diesen Ansatz für die Erstellung von Offline-Webanwendungen übernommen und verfügt möglicherweise über einige relevante Ressourcen. Diese Arten von Anwendungsfällen erfordern nicht nur, dass Sie Ihre Datenzugriffsebene für Clients öffnen, sondern auch die Datenspeicherung! Ich weiß, ich weiß. Scheint verrückt, oder?

Die Bedenken in Bezug auf solche Apps, die zuerst offline sind, ähneln denen, die Sie gefragt haben, nur eine Ebene entfernt. Es scheint mir relevant zu sein. Angesichts der Tatsache, dass Sie den direkten Datenzugriff für Kunden öffnen, stellt sich die Frage, wie Sie die Auswirkungen eines böswilligen Benutzers begrenzen können. Nun, es gibt viele Strategien, aber sie sind nicht offensichtlich, wenn Sie einen traditionelleren Entwicklungshintergrund haben.

Das erste Missverständnis ist, dass das Offenlegen der Datenbank das Offenlegen aller Daten bedeutet. Nehmen Sie zum Beispiel CouchDB; Datenbanken in CouchDB sind kompakt, sodass Sie sich keine Gedanken darüber machen müssen, Hunderttausende separater Datenbanken auf einem Server zu erstellen. Benutzer können nur auf Datenbanken zugreifen, für die ihnen die Berechtigung zum Lesen oder Schreiben erteilt wurde (geschweige denn auf Validierungsfunktionen und das, was nicht mit CouchDB zu tun hat), sodass sie nur auf eine Teilmenge der Daten zugreifen können.

Das zweite Missverständnis ist, dass ein Benutzer, der auf Daten kackt, ein Problem ist! Wenn Benutzer ein Replikat einer Datenbank erhalten, können sie auf alles verzichten, ohne andere Benutzer zu beeinträchtigen. Sie sollten die Änderungen jedoch überprüfen, bevor Sie die Daten zurück in den "zentralen" Speicher replizieren. Denken Sie an Git - Benutzer können in Zweigen, Forks und lokalen Repositorys tun, was immer sie möchten, ohne dass dies Auswirkungen auf den Master-Zweig hat. Das Zusammenführen zum Meister erfordert viel Zeremonie und erfolgt nicht blind.

Ich baue derzeit ein System mit CouchDB, in dem Benutzer zusammenarbeiten müssen, um ein Dataset zu erstellen, das dann über einen QA / QC-Workflow "veröffentlicht" wird. Die Zusammenarbeit wird auf einer Replik der Daten ausgeführt (wir nennen dies eine Bereitstellungs- oder Arbeitsdatenbank), und nach Abschluss führt eine verantwortliche Person eine QS / QC für die Daten durch und repliziert sie erst dann zurück in das Hauptrepository.

Daraus ergeben sich viele Vorteile, die in anderen Systemen nur schwer zu erreichen sind - wie Versionskontrolle, Replikation und Zusammenarbeit (Offline-Arbeiten!) Für herkömmliche dreistufige CRUD-Anwendungen sind extrem schwierig.

Mein Rat - wenn Ihre Bewerbung "traditionell" ist, dann machen Sie es auf die traditionelle Art und Weise. Wenn eines der oben genannten Dinge (obwohl es noch viel mehr gibt ...) auf Sie zutrifft, sollten Sie alternative Architekturen in Betracht ziehen und bereit sein, quer zu denken.


0

Ich denke, dass es bei all Ihren Annahmen machbar ist, direkt vom Client zur Datenbank zu wechseln. Es ist jedoch vernünftig zu prüfen, ob Ihre Annahmen gültig sind und wahrscheinlich auch in Zukunft so bleiben.

Ich würde mir Sorgen machen, dass es in Zukunft möglicherweise nicht für alle in Ordnung ist, alle Daten zu lesen, und insbesondere, dass in Zukunft mehr Geschäftslogik entwickelt wird. Beides ist wahrscheinlicher, wenn das Projekt erfolgreich ist.

Solange Sie sich selbst überlassen, diese Probleme in Zukunft zu lösen, und wenn Sie sich tatsächlich mit ihnen befassen müssen, denke ich, dass Ihr Design funktionieren wird. Ich denke, Sie müssen besonders vorsichtig sein, um Bedenken im JavaScript-Code auszuräumen, und einige davon werden möglicherweise später auf dem Server neu geschrieben.

Aber ich konnte definitiv sehen, wo es sich lohnen könnte, dies später zu tun, im Gegensatz zu dem Vorteil, dass heute weniger bewegliche Teile vorhanden sind.


Guter Punkt. Dies ist definitiv ein enger Anwendungsfall, sodass Sie ihn auf keine Anwendung anwenden können.
Chris Smith

0

Zunächst einmal vielen Dank für die OUT OF THE BOX-Frage .... :)

Aber was ich vorschlagen würde, ist; Versuchen Sie immer, eine Trennung zwischen Ihren 3 Schichten aufrechtzuerhalten. Dies sind Presentation / Business and Database oder DAO, da dies die beste Vorgehensweise bei solchen Anforderungen und Setups ist, bei denen täglich viele Änderungen vorgenommen werden.

In einfachen Welten sollte Ihre Präsentationsschicht nicht über die Datenbankschicht informiert sein. Das Format einiger Datumstypfelder kann sich von der Präsentationsschicht und der Datenbankschicht unterscheiden, sodass der Benutzer das für seine Bedürfnisse geeignete Datumsformat auswählen kann.

Und Business Logic muss wie eine Kopplung zwischen Präsentationsschicht und Datenbank- / Dao-Schicht wirken, z. B. das Casting der Felder. Einige Geschäftsvalidierungen usw. sollten auf Business Layer und nicht in JavaScript-Abschnitten wie in Ihrer Frage behandelt werden.

Diese Trennung erleichtert und vereinfacht die Durchführung komplexer Szenarien, Funktionen und sogar komplexer Validierungen. Der beste Vorteil ist: Sie können unterschiedliche Technologien zum Implementieren dieser Ebenen verwenden und diese je nach Geschäftsanforderungen oder -umfang ändern.

Vielen Dank


0

Wenn Sie SQL in JavaScript erstellen und an die Datenbank senden möchten, die die Rechte usw. überprüft, wäre dies aus Sicherheitsgründen eine Katastrophe. Ganz einfach, weil Sie beim Erstellen einer API und beim Erstellen von Abfragen selbst nur die begrenzte Anzahl von Abfragen aus Sicherheitsgründen analysieren müssen. Wenn die Abfragen außerhalb Ihres Systems erstellt wurden, haben Sie möglicherweise eine unbegrenzte Anzahl von Tricks, die jemand ausführen kann.

Dies ist jedoch nicht der Fall, da Sie eine Schlüsselwertdatenbank verwenden (so fair CouchDB im Allgemeinen in diese Kategorie fällt). Die Datenbankschnittstelle selbst ist eine Art Mittelschicht und wird vom Apache-Team aus Sicherheitsgründen getestet. Aufgrund der relativ einfachen JavaScript-API ist dies noch einfacher auf potenzielle Fehler zu analysieren als solche komplizierten Schnittstellen, über die JSF-Anwendungen verfügen.

Dies kann eine sichere Lösung sein, wenn Sie komplexe Sicherheitstests durchführen. Dies kann sogar einfacher sein als bei der Verwendung von Frameworks wie JSF, die häufig schwer lesbare APIs verwenden. Sicherheit durch Unbekanntheit ist keine Lösung.

In Bezug auf Ihre Frage wird es sowieso keinen direkten Zugriff auf die Datenbank geben. Direkter Zugriff wäre das Erstellen von SQL-Abfragen in JavaScript (leider habe ich solche Lösungen gesehen). In Ihrem Fall stellt die CouchDB selbst die Isolationsschicht bereit. Sie könnten es natürlich in Ihre API einbinden, um es zu härten, aber solange Sie einfach testen können, was ein bestimmter Benutzer tun kann, und wenn die Sicherheitsbeschränkungen für Sie gelten, haben Sie eine sichere und robuste Lösung ohne zusätzliche Ebenen.


0

Ich sehe zwei Probleme:

1. Enge Kopplung: Ändern Sie Ihre DB-Option? Nun, jetzt musst du auch deinen gesamten clientseitigen Code ändern. Vertrau mir. Wir brauchen keine Probleme mehr auf der Client-Seite.

2. TMI-Sicherheitsproblem: Enthüllt viel zu viel darüber, wie Dinge funktionieren. Auth ist zwar immer noch ein Hindernis, aber das Auffinden eines Exploits ist um einiges einfacher, wenn Sie genau wissen, was auf der Serverseite passiert.

Eine sehr, sehr dünne Mittelschicht könnte der bessere Weg sein.


-1

Ihr Client kann Ihre Web-App nicht verwenden, wenn Javascript deaktiviert ist (oder auf dem Browser seines Geräts nicht unterstützt wird), wenn Javascript die einzige Datenbankzugriffsebene ist.


2
Eh, nicht allzu besorgt darüber. Der größte Teil des Webs basiert sowieso auf Javascript. Möglicherweise muss ich nur die <noscript> -Tags herausbrechen und ihnen mitteilen, dass sie sie aktivieren müssen, wenn meine Site (und 80% der anderen da draußen) funktionieren soll.
Chris Smith
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.