ilch Forum » Ilch CMS 2.X » Allgemein » PDO / Prepared Statements

Geschlossen
  1. #1
    User Pic
    BadRandolph Mitglied
    Registriert seit
    31.05.2006
    Beiträge
    26
    Beitragswertungen
    8 Beitragspunkte
    Hallo zusammen,

    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
    0 Mitglieder finden den Beitrag gut.
  2. #2
    User Pic
    Mairu Coder
    Registriert seit
    16.06.2006
    Beiträge
    15.334
    Beitragswertungen
    386 Beitragspunkte
    Wie du ganz richtig schreibst, muss man wissen, wie man es verwendet. Dabei ist am Ende recht egal, was benutzt wird.

    Wenn du dir die Arbeit machen möchtest, will ich dich nicht aufhalten. Der Mehrwert dabei ist allerdings recht gering.

    Dabei muss ich dir Recht geben, dass es nicht wirklich clever ist prepared statements nicht anzubieten, da auch mysqli diese ja unterstützt.

    Man könnte btw. die named prepared Statements auch numerierte Prepared Statements umlegen, in der query Funktion und somit insgesamt recht wenig ändern.

    Und ich möchte dir nicht vorenthalten, dass PDO auch Nachteile ggü. mysqli hat. de2.php.net/manual/en/mysqlinfo.api.choosing.php

    Und das man zwischen verschiedenen Datenbanksystemen wechseln kann, ist meiner Meinung nach eher ein Mythos, da jedes Datenbanksystem seine eigene Syntax hat, sobald man sich ein klein wenig vom SQL Standard entfernt. Das einfachste Beispiel ist LIMIT.
    Und auch immer mal ein Blick auf die FAQ werfen. | Mairus Ilchseite
    1 Mitglieder finden den Beitrag gut.
Geschlossen

Zurück zu Allgemein

Optionen: Bei einer Antwort zu diesem Thema eine eMail erhalten