Validierung der Dateneingabe - Wo? Wie viel? [geschlossen]

27

Die Validierung von Dateneingaben war für mich immer ein ziemlicher interner Kampf.

Kurz vor dem Hinzufügen eines echten Sicherheitsrahmens und -codes zu unserem Umschreibprojekt für Legacy-Anwendungen (bei dem der kartenschlossstarke Legacy-Sicherheitscode und die Datenvalidierung so gut wie erhalten bleiben), frage ich mich erneut, wie viel ich validieren soll. wo usw.

In meinen 5 Jahren als professioneller Java-Entwickler habe ich meine persönlichen Regeln für die Validierung von Dateneingaben und Sicherheitsmaßnahmen erstellt und verfeinert. Da ich meine Methoden verbessern möchte, möchte ich einige Ideen von euch hören. Allgemeine Regeln und Prozeduren sind in Ordnung und auch Java-spezifische.

Zusammengefasst sind dies meine Richtlinien (dargestellt in einem dreistufigen Webanwendungsstil) mit kurzen Erklärungen:

  • 1st Tier Client-Seite (Browser): minimale Validierung, nur unveränderliche Regeln (obligatorisches E-Mail-Feld, muss einen Artikel auswählen und dergleichen); Verwendung einer zusätzlichen Validierung wie "zwischen 6 und 20 Zeichen" weniger häufig, da dies den Wartungsaufwand für Änderungen erhöht (kann hinzugefügt werden, sobald der Geschäftscode stabil ist);

  • Serverseite der ersten Ebene (Handhabung der Webkommunikation, "Controller"): Ich habe keine Regel für diese, bin jedoch der Meinung, dass hier nur Datenmanipulations- und Assembly- / Parsing-Fehler behandelt werden sollten (Geburtstagsfeld ist kein gültiges Datum). Das Hinzufügen weiterer Validierungen hier macht es leicht zu einem wirklich langweiligen Prozess.

  • 2nd Tier (Business Layer): Absolute Validierung, nicht weniger; Eingabedatenformat, Bereiche, Werte, interne Statusprüfung, ob die Methode jederzeit aufgerufen werden kann, Benutzerrollen / -berechtigungen usw. Verwenden Sie so wenig Benutzereingabedaten wie möglich und rufen Sie diese bei Bedarf erneut aus der Datenbank ab. Wenn wir abgerufene Datenbankdaten auch als Eingabe betrachten, würde ich sie nur dann validieren, wenn bekannt ist, dass einige bestimmte Daten auf der DB unzuverlässig oder verfälscht genug sind - starke Typisierung erledigt den größten Teil der Arbeit hier, IMHO;

  • 3. Schicht (Datenschicht / DAL / DAO): Ich habe nie geglaubt, dass hier viel Validierung erforderlich ist, da nur die Geschäftsschicht auf die Daten zugreifen soll (validieren Sie möglicherweise in einigen Fällen wie "param2 darf nicht null sein, wenn param1 wahr ist"); Beachten Sie jedoch, dass, wenn ich "hier" meine, "Code, der auf die Datenbank zugreift" oder "SQL-ausführende Methoden", die Datenbank selbst genau das Gegenteil ist.

  • Die Datenbank (Datenmodell): muss so durchdacht, stark und selbstsicher sein, dass falsche und beschädigte Daten in der Datenbank mit guten Primärschlüsseln, Fremdschlüsseln, Einschränkungen, Datentyp / Länge / Größe so weit wie möglich vermieden werden / Präzision und so weiter - ich lasse Auslöser aus, da sie ihre eigene private Diskussion haben.

Ich weiß, dass eine frühe Datenvalidierung in Bezug auf die Leistung nett ist, aber eine wiederholte Datenvalidierung ist ein langweiliger Prozess, und ich gebe zu, dass die Datenvalidierung selbst ziemlich ärgerlich ist. Deshalb überspringen so viele Programmierer es oder machen es auf halbem Weg. Außerdem ist jede doppelte Überprüfung ein möglicher Fehler, wenn sie nicht immer synchronisiert werden. Das sind die Hauptgründe, aus denen ich es heutzutage bevorzuge, die meisten Validierungen auf Kosten von Zeit, Bandbreite und CPU bis zur Business-Ebene zu überlassen. Ausnahmen werden von Fall zu Fall behandelt.

Sag mal, wie findest du das? Gegensätzliche Meinungen? Haben Sie andere Verfahren? Ein Verweis auf ein solches Thema? Jeder Beitrag ist gültig.

Hinweis: Wenn Sie an Java denken, basiert unsere App auf Spring MVC und MyBatis (Leistung und schlechtes Datenbankmodell schließen ORM-Lösungen aus). Ich plane, Spring Security als Sicherheitsanbieter und JSR 303 (Hibernate Validator?) Hinzuzufügen.

Vielen Dank!


Bearbeiten: einige zusätzliche Klarstellung auf der 3. Ebene.

mdrg
quelle
Mein Rat ist zu studieren, wie Hibernate Validator funktioniert. Ich habe JSR 303 nicht als nützlich erachtet, da die Validierung während der Persistenz einsetzt, während einige meiner Regeln lange vor der Persistenz erzwungen werden mussten, da ich Geschäftsregeln hatte, die auf einer grundlegenden Validierung beruhten. Meiner Meinung nach funktioniert es für ein sehr geschlossenes Modell; Vielleicht habe ich es falsch benutzt, aber ich habe nie jemanden gefunden, der andere Erfahrungen gemacht hat als ich.
Vineet Reynolds
@Vineet Reynolds Ich habe es bereits für die Formularvalidierung mit Spring MVC verwendet, es ist wirklich eine großartige Kombination. Ich erhalte mit wenig oder gar keinem Aufwand eine serverseitige Validierung mit fein abgestimmten Nachrichten und einem entsprechenden Fehler, der dem Benutzer angezeigt wird. Ich muss es noch vollständig auf serverseitigen Objekten testen, da ich mir der Vorteile nicht sicher bin. Schauen Sie sich dieses Beispiel an, so habe ich es benutzt: codemunchies.com/2010/07/…
mdrg
2
setzen zu viel Validierung. Überall verdammt diese Benutzereingaben @ #! ! @@!
Chani

Antworten:

17

Ihre Validierung sollte konsistent sein. Wenn ein Benutzer also Daten in das Webformular eingibt, deren Gültigkeit festgestellt wurde, sollten diese aufgrund einiger Kriterien, die Sie auf der Clientseite nicht implementiert haben, von der Datenbankebene nicht abgelehnt werden.

Als Benutzer wäre nichts ärgerlicher, als eine Seite voller Daten scheinbar richtig einzugeben und erst nach einem bedeutenden Rundgang durch die Datenbank zu erfahren, dass etwas nicht stimmt. Dies wäre insbesondere dann der Fall, wenn ich dabei eine Client-Validierung auslösen würde.

Sie müssen die Validierung auf verschiedenen Ebenen haben, während Sie diese offenlegen, und haben möglicherweise keine Kontrolle darüber, wer sie anruft. Sie müssen also (so weit wie möglich) dafür sorgen, dass Ihre Validierung an einem Ort definiert und von jedem Ort aus aufgerufen wird, an dem sie benötigt wird. Wie dies arrangiert wird, hängt von Ihrer Sprache und Ihrem Framework ab. In Silverlight (zum Beispiel) können Sie es auf der Serverseite definieren und mit geeigneten Attributen wird es auf die Clientseite kopiert, um dort verwendet zu werden.

ChrisF
quelle
2
+1 Absolut. Ich wollte dasselbe über ASP.NET MVC sagen, aber Sie haben mich geschlagen. :) Wirklich, wir MÜSSEN nur vor Ort validieren, um sicherzustellen, dass ein System in einem gültigen Zustand bleibt. Der Rest der Validierung wie auf der Client-Seite besteht darin, die Benutzerfreundlichkeit zu verbessern und die für den Benutzer verschwendete Zeit zu verkürzen. Konsistenz ist der Schlüssel.
Ryan Hayes
2
In Bezug auf die "Rundreise" sehe ich kein Problem, solange die Seite mit den richtigen Fehlermeldungen neu geladen wird und alle Felder mit dem ausgefüllt werden, was Sie zuvor eingegeben haben. Wenn es zu lange dauert, bis die Fehler behoben sind, ist dies ein Kandidat für eine zusätzliche clientseitige Validierung.
mdrg
Und sicher, wenn die Validierung problemlos über die App repliziert werden kann, gibt es keinen Grund, dies zu verschwenden. Auf der Serverseite ist es einfach, aber auf der Clientseite wird es ohne solche Validierungswerkzeuge wie das von Ihnen erwähnte sehr frustrierend (z. B. viel JS-Validierungscode schreiben, genau wie der, den Sie auf dem Server geschrieben haben). .
mdrg
9

In einem relationalen System sehe ich es als einen dreischichtigen Ansatz. Jede Ebene wird durch die folgenden eingeschränkt:

  • Präsentation / Benutzeroberfläche
    • einfache Eingabevalidierung
    • Fahren Sie nicht fort, wenn die Eingabe im falschen Format ist
    • "Gate" -Clients fordern den Server auf, Roundtrips zu reduzieren, um die Benutzerfreundlichkeit zu verbessern und die Bandbreite / Zeit zu reduzieren
  • Logik
    • Geschäftslogik und Autorisierung
    • Lassen Sie nicht zu, dass Benutzer Dinge tun, die sie nicht tun dürfen
    • Behandle hier "abgeleitete" Eigenschaften und Zustände (Dinge, die in der Datenbank denormalisiert würden)
  • Daten
    • die wesentliche Datenintegritätsschicht
    • lehne es absolut ab , irgendwelchen Müll aufzubewahren
    • die DB selbst erzwingt Datenformate (int, date, etc.)
    • Verwenden Sie Datenbankeinschränkungen, um ordnungsgemäße Beziehungen sicherzustellen

Die ideale Antwort darauf wäre ein System, mit dem Sie die Einschränkungen auf allen drei Ebenen an einem Ort definieren können. Dies würde eine Codegenerierung für SQL und zumindest eine datengesteuerte Validierung für den Client und den Server beinhalten.

Ich weiß nicht, ob es hier eine Silberkugel gibt ... aber da Sie in der JVM sind, würde ich Rhino empfehlen, um mindestens den JavaScript-Validierungscode zwischen Client und Server zu teilen. Schreiben Sie Ihre Eingabevalidierung nicht zweimal.

John Cromartie
quelle
Ich werde einen Blick auf Rhino werfen. Wenn es sich irgendwie in die MVC-Formularvalidierung von Spring integrieren lässt, umso besser.
mdrg
7

3. Schicht (Datenschicht / DAL / DAO): Ich habe nie geglaubt, dass hier viel Validierung erforderlich ist, da nur die Geschäftsschicht auf die Daten zugreifen soll. .

Das ist so falsch. Der wichtigste Ort für die Validierung ist die Datenbank selbst. Die Daten sind fast immer von mehr als der Anwendung betroffen (auch wenn Sie glauben, dass dies nicht der Fall ist), und es ist bestenfalls verantwortungslos, keine geeigneten Steuerelemente in die Datenbank einzufügen. Die Entscheidung, dies nicht zu tun, führt zu einem größeren Verlust der Datenintegrität als jeder andere Faktor. Datenintegrität ist entscheidend für die langfristige Nutzung der Datenbank. Ich habe noch nie eine Datenbank gesehen, bei der Integritätsregeln auf Datenbankebene, die gute Daten enthielten, nicht durchgesetzt wurden (und ich habe die Daten in buchstäblich Tausenden von Datenbanken gesehen).

Er sagt es besser als ich: http://softarch.97things.oreilly.com/wiki/index.php/Database_as_a_Fortress

HLGEM
quelle
Ich stimme dem letzten Teil dieses Artikels zu, ich glaube, ich habe mich in diesem Teil nicht klar ausgedrückt. Ich habe die Frage mit weiteren Details aktualisiert. Vielen Dank!
mdrg
2

All das setzt voraus, dass Entwickler und Betreuer perfekt sind und perfekten Code schreiben, der immer perfekt läuft. Zukünftige Software-Releases kennen alle Annahmen, die Sie getroffen und nie dokumentiert haben, sowie Benutzer und Hacker, die Daten auf eine Weise in das System eingeben, die Sie sich nie vorgestellt haben.

Sicher, zu viel Validierung ist eine schlechte Sache, aber wenn Programme, Netzwerke und Betriebssysteme perfekt sind, werden Hacker nicht durch Ihre Firewall gelangen, und ein DBA wird die Datenbank wahrscheinlich nicht manuell "optimieren".

Zeichnen Sie Grenzkreise um die Dinge, identifizieren Sie die Fehlermodi, vor denen sie schützen, und führen Sie eine angemessene Überprüfung für diese Grenze durch. Zum Beispiel sollte Ihre Datenbank niemals ungültige Daten sehen, aber wie könnte es passieren und was ist, wenn dies der Fall ist? Wer ist Ihr Benutzer, was kostet der Ausfall?

Wenn Sie sich mit Sicherheitsmodellen der physischen Welt befassen, sollte die Sicherheit in Schichten wie eine Zwiebel vorliegen. Eine dicke Mauer gilt als mangelhafte Sicherheit. Die Datenvalidierung sollte auf die gleiche Weise betrachtet werden.

mattnz
quelle
1

Zwei kurze, allgemeine Validierungsregeln:

Wenn Sie einen Anruf tätigen, der keine Garantie bietet, wird eine Meldung (Fehler, Ausnahme) ausgegeben, die Sie über ungültige Eingaben auf eine Weise informiert, die Sie an Ihren Anrufer zurückgeben können.

Wenn Sie die Daten anderweitig bearbeiten (Entscheidungen treffen, rechnen, speichern usw.), validieren Sie sie.

Blrfl
quelle