leider weiß ich nicht ob das Thema schonmal diskutiert wurde, im Forum und Redmine habe ich dazu aber nichts gefunden.
Es geht um folgendes:
Die Datenbankklasse von Ilch 2.0 verwendet ja die PHP mysqli-Extension. Nun erlaubt mysqli leider keine Prepared Statements mit Named Parametern [1]. Prepared Statements können die Sicherheit einer Applikation drastisch erhöhen, sofern sie überall verwendet werden [2]. Die Standard PHP PDO Implementierung ist leider sehr umständlich, das könnte man über einen Wrapper (so wie es der Query Builder macht) aber etwas schöner und einfacher für den Anwender verpacken.
Zudem würde sich PDO auch sehr schön im OOP / MVC-Stil von Ilch 2.0 machen (natürlich meine subjektive Meinung) und bringt unterstützung für 12 Datenbanksysteme mit (im Web Bereich verwendet man ja meist nur MySQL, von daher wahrscheinlich kein großes Kriterium)
=> Die Umstellung wäre, sofern das überhaupt in Frage kommt, extrem. Wie gesagt, erhöhte Sicherheit bieten Prepared Statements nur, wenn sie überall eingesetzt werden. Falls man darüber Nachdenkt wäre es aber wahrscheinlich ratsam, das noch in der Alpha zu machen - später wäre es nur noch schlimmer.
EDIT: Vielleicht wäre es garnicht so schlimm, die normale Syntax funktioniert ja weiterhin. Man müsste nur den Connect auf PDO umstellen, ein paar Funktionen im QueryBuilder ändern und zusätzliche Parameter für die Values einführen. Bestehender Code wäre davon wahrscheinlich sogar unberührt wenn mich nicht alles täuscht...
Gibt es Meinungen dazu?
Grüße
[1]: Mit Prepared Statements mit Named Parametern kann man, sofern man einen kleinen Wrapper hat, so seine Abfragen schreiben:
$result = $db->query('SELECT * FROM [prefix]_tabelle WHERE username = :username', [ 'username' => $_GET['username'] ]);
Hintergrund: $_GET Parementer sollte man niemals ungeprüft verwenden, das ist natürlich ein extremes Beispiel. Prinzipiell ist dieses Statement aber trotzdem sicher (auch ohne Escape [3]) da die MySQL-Abfrage selbst getrennt von den Paremetern vom Client (=PHP) an den Server (=MySQL Server) übertragen wird, dem die Values wiederum sehr egal sind beim Aufbau der Abfrage. Daher ist es nicht mehr möglich, eine SQL-Injection damit aufzubauen.
[2]: Das ganze funktioniert nur, wenn sie wirklich überall verwendet werden. Sonst wäre z.B. das hier möglich:
// in $_GET['username'] steht z.B. 'admin' OR true OR 'admin $result = $db->query('INSERT INTO [prefix]_users SET username = :username', [ 'username' => $_GET['username'] ]); // Kein Problem, SQL-Injection durch Prepared Statements verhindert. // Nächste Abfrage: $result = $db->query('UPDATE [prefix]_users SET is_sysadmin = 1 WHERE username = \'' . $result->username . '\'); // Nun findet eine SQL-Injection auf einem zweiten Weg statt => Schlecht.
[3]: Escapes haben den Nachteil, dass sie unter Umständen mit manchen Zeichensätzen oder Hex-Code nicht richtig funktionieren und zudem SQL-Injections auch nicht immer verhindern können. Zudem ist es schwieriger immer und an jeder Stelle auf richtiges Escaping zu achten anstatt einfach immer die o.g. Syntax für Abfragen zu verwenden, die dann auch noch kürzer ist. Der QueryBuilder sorgt zwar für Escaping, jedoch kann man Abfragen auch ohne QueryBuilder ausführen bzw. muss man das an manchen Stellen bei komplexen Funktionen, für die der QueryBuilder keinen Wrapper bereitstellt.
verwendete ilch Version: 2.0 (alpha)
Zuletzt modifiziert von BadRandolph am 30.11.2016 - 00:18:39