Verhinderung von SQL-injection ohne prepared statements (JDBC)
Habe ich ein Datenbank-log-appender, der fügt eine variable Anzahl der log-Zeilen in der Datenbank, jeder einmal in eine Weile.
Ich möchte erstellen Sie eine SQL-Anweisung in einer Weise, die verhindert, dass SQL-injection, aber nicht mit server-side prepared statements (weil ich habe eine variable Anzahl von Zeilen in jeder auswählen, caching, Ihnen nicht helfen wird, aber Schaden könnte performance hier).
Ich mag auch die Bequemlichkeit der prepared Statements, und bevorzugen Sie string-concatination. Gibt es so etwas wie eine 'client-Seite-vorbereitete Anweisung' ?
- Ich glaube nicht, dass die Verwendung von prepared-Anweisung aktiviert caching (außer vielleicht die Aussagen selbst) auf der server-Seite.
- PreparedStatements werden kann oder nicht server-Seite. Das hängt von der Datenbank, die jdbc-Treiber verwendet, und einige andere Dinge.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es klingt wie Sie haven ' T getestet die einfachste Lösung - prepared statements. Sie sagen, dass Sie verletzen könnte Leistung" aber erst wenn Ihr es getestet habe, Sie wirklich nicht wissen.
Ich würde definitiv test vorbereitet-Anweisungen zuerst. Auch wenn Sie tun behindern die Leistung etwas, bis Sie getestet haben und Ihnen, die Sie nicht wissen, ob Sie noch erreichen die Leistung, die Sie benötigen.
Warum verbringen Zeit damit, sich um alternative Lösungen finden, wenn Sie noch nicht versucht das offensichtlichste?
Wenn Sie feststellen, dass prepared statement (execution plan caching ist teuer, Sie können auch feststellen, es gibt DB-spezifische Möglichkeiten von tuning oder deaktivieren.
Nicht sicher, ob ich verstehe Ihre Frage richtig. Gibt es etwas in
PreparedStatement
, die nicht passen Ihre Bedürfnisse?Ich denke, dass, ob oder nicht die Anweisung wird auf dem server zwischengespeichert Seite ist eine Implementierung detail des Datenbank-Treibers und der Datenbank, die Sie verwenden; wenn Sie Ihre Abfrage/Anweisung ändert im Laufe der Zeit als dieses sollte das keinen Einfluss haben - die-Cache/compiled Aussagen, die einfach nicht genutzt werden.
Erste, Jon ' s Antwort, dass Sie gehen sollte mit der offensichtlichsten Lösung, bis die Leistung gemessen wird, ein problem ist sicherlich der richtige Ansatz im Allgemeinen.
Ich glaube nicht, dass deine performance-Bedenken sind fehl am Platz. Ich habe sicherlich gesehen vorkompilierte komplexe Aussagen scheitern dramatisch auf die performance-Skalierung (auf MS-SQL 2000). Der Grund dafür ist die Anweisung war so Komplex, dass es hatte mehrere mögliche Ausführungspfade je nach dem Parameter, aber die Zusammenstellung gesperrt, eine in die für einen Satz von Parametern, und der nächste Satz von Parametern, die zu langsam waren, in der Erwägung, dass eine Neukompilierung erzwingen würden eine Neuberechnung der Ausführungsplan mehr für den anderen Satz von Parametern.
Aber das Anliegen ist sehr weit hergeholt, bis Sie es in der Praxis.
Das zugrunde liegende problem ist hier, dass die parameter der Flucht ist Datenbank-spezifisch, so dass es sei denn, der JDBC-Treiber für Ihre Datenbank geben Sie etwas non-standard, dies zu tun (sehr unwahrscheinlich), sind Sie gehen zu müssen, um eine andere Bibliothek oder ein anderes Flucht-Mechanismus, der sehr spezifisch für diese eine Datenbank.
Aus der Formulierung Ihrer Frage, es klingt nicht wie Ihre Leistung betrifft noch zu dem Punkt, der verdient finden (oder entwickeln) eine solche Lösung.
Es sollte auch angemerkt werden, dass, obwohl der JDBC-Treiber kann nicht alle sich so benehmen, technisch, entsprechend der Spezifikation der Vorkompilierung werden soll, zwischengespeichert, in das PreparedStatement-Objekt, und wenn Sie das wegzuwerfen und ein neues PreparedStatement jeder Zeit, sollte es eigentlich nicht sein-caching nichts, so dass die ganze Frage kann stumm sein und müsste untersucht werden, für Ihren spezifischen JDBC-Treiber.
Aus der spec:
was ist falsch mit der Verwendung eine regelmäßige vorbereitete Anweisung z.B. in den folgenden pseudocode:
Einer intelligenten Datenbank-Implementierung batch-mehrere Einsätze in einem communications-exchange-w/die Datenbank-server.
Ich kann nicht einen Grund denken, warum sollten Sie nicht verwenden vorbereitete Anweisungen. Wenn Sie diese auf einem J2EE-server mit connection-pooling der server hält die verbindungen offen, und der server speichert Ihr den Zugriff/die Ausführung der Pläne. Es ist nicht das Daten-caches!
Wenn Sie schließen Sie die Verbindung jedes mal, wenn, dann sind Sie wahrscheinlich nicht gewinnen jede Leistung. Aber Sie bekommen noch die SQL-injection-Prävention
Meisten java-performance-tuning-Bücher werden Ihnen sagen das gleiche:
Java performance tuning
Prepared Statements kümmern sich nicht um client-oder server-Seite.
Verwenden Sie Sie, und löschen Sie keine SQL-string-Verkettung. Es gibt nicht einen einzigen Grund, nicht mit Vorbereiteten Anweisungen sind.