Sven Rautenberg: Sicherheit

Beitrag lesen

Moin!

Ich nutze Prepared Statements derzeit wegen der erhofften Sicherheit.

Leider ja aber nicht konsequent, wie man an deinem Code sieht. Du benutzt einmal für die Abfrage eines einzigen Datensatzes ein Prepared Statement, und dann für die Abfrage eines weiteren Datensatzes einen normalen Query.

Ich habe gelesen, dass Prepared Statements auch schneller bearbeitet werden, dass ist auch einer der gründe ; oder ist das auch eher zu vernachlässigen?

Das ist zu vernachlässigen, wenn du den Query nur ein einziges Mal durchführst. Der Geschwindigkeitsvorteil kommt zum Tragen, wenn du z.B. ein SELECT vorbereitest, mit Platzhalter im WHERE, und dann eine Folge von vielleicht hundert Aufrufen (d.h. hundert SELECTs) startest, jeweils mit unterschiedlichen Werten für den WHERE-Teil.

Obendrein ist deine Anwendung von mysqli extrem unterschiedlich. Du mixt - wie erwähnt - Prepared Statements und normale Querys. Dann auch noch die (viel elegantere) objektorientierte Methode mit der prozeduralen (mysqli_real_escape_string-Aufruf mittendrin).

Abgesehen davon ist dein Programmierstil alles andere als schön. Zu kritisieren aus meiner Sicht ist:

Variablenkopiererei! DAS ist wirklich ÜBEL! Im Skriptverlauf entstehen bei dir unzählige Variablen, werden ineinander kopiert, weisen eventuell - aber nicht unbedingt immer, das hängt von den Verzweigungen in diversen IFs ab - den identischen Inhalt auf, werden irgendwann einfach nicht mehr benutzt, aber nicht entsorgt - und man muss Angst haben (ich habe sie zumindest), dass durch irgendeinen dummen Zufall, Vertipper, oder Fehler diese Variablen später doch noch mal herangezogen werden und irgendwelche negativen Konsequenzen verursachen.

Beispiele für solche unsicheren, weil sinnlos verwendeten Variablen sind:
$mein_server_request, $query_request_check, $site_exists, $aktuelle_gruppe, $aktuelle_link.

Weiterhin fragst du Dinge aus der DB ab, die du nirgends benutzt:
$haupt_gruppe_1, $url_link

Was mich zu der Ansicht treibt, dass deine ZWEI Querys auch prima in EINEN Query gepaßt hätten.

Die Krönung der sinnlosen Kopiererei aber ist der Transfer des wunderschönen assoziativen Arrays, welches aus der zweiten DB-Abfrage kommt, in tausend Einzelvariablen, nur um dann vor dem finalen Transfer der Inhalte in das Smarty-Template diese Einzelvariablen wieder in ein komplettes assoziatives Array zu stecken.

Gewiß, auf dem Weg von DB-Abfrage zu Template kommen noch ein paar zusätzliche Werte hinzu oder werden berechnet, aber dafür braucht man keine Einzelvariablen, das geht alles auch mit dem assoziativen Array!

Hier hast du eine "nette" Bad-Word-Liste. Dumm nur, dass du auf vermutlich genauso wirksame Bestandteile wie "SCRIPT" oder "INCLUDE" in Upper Case nicht reagierst.

Ungeklärt bleibt, warum diese Badwordliste existiert. Der Code zeigt eindeutig, dass die REQUEST_URI direkt als Abfragekriterium in der Datenbank dient - allerdings muss ich gestehen, dass dieser Wert auch mehrfach wieder aus der Datenbank zurückgelesen, wieder als Parameter in Querys reingesteckt und wieder ausgelesen wird, so dass man die Spur der Herkunft leicht aus den Augen verlieren kann.

Umso wichtiger, dass die Herkunftsinformation nicht verloren geht - was sie derzeit definitiv tut.

Die weitere Verarbeitung im Script passiert dann Intern, also keine Usereingaben oder sonstiges.

Ich kann in deinem Skript nicht erkennen, dass es dort eine eindeutig definierte Grenze gibt, die exakt trennt, welcher Variableninhalt "böse vom User" ist, und welcher als "per Definition gut, weil validiert/aus Tabelle entnommen/etc." gilt.

Solch eine Grenze spiegelt sich in der Regel in der Benennung der Variablen wider. Ich persönlich finde, dass alles, was in den $_EGCPS-Variablen steht, diese nie ohne irgendeine Schutzfunktion verlassen sollte, und dass beispielsweise Formularinhalte, die eine Validierung durchlaufen haben, genauso gesammelt als Array in einer anderen Variablen (oder als Eigenschaft eines filternden Objektes) zur Verfügung stehen sollten.

Meine Faustregel ist da immer: Bevor ich irgendwas selbst parse, verlasse ich mich lieber auf die vorgefertigten Funktionen der benutzten Programmiersprache, die mir die benötigten Daten u.U. mundgerecht servieren.

Ich ging davon aus, dass Prepared Statements die benötigte Sicherheit garantieren, welche vorgefertigten Funktionen gibt es denn noch für MySQL?

Ich bezog mich auf das URL-Parsen und würde im Zweifel den Inhalt von $_GET & Co. vorziehen.

- Sven Rautenberg

--
"Love your nation - respect the others."