mysqli vs. PDO, Bugs, Sicherheit

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • mysqli vs. PDO, Bugs, Sicherheit

    Hallo Community

    Ich will mich nun mal wieder PHP (5.2.6) widmen, komme sonst aber aus der ASP.NET Ecke. Aufgrund dessen möchte ich möglichst alles objekt-orientiert umsetzen, einfach der Gewohnheit wegen. Ich habe mich schon etwas eingelesen in die PHP-OOP und vermisse vieles, aber das wird schon.

    Nun stellt sich mit die Frage, ob ich zu mysqli oder doch lieber zu PHP Data Objects greifen soll. Da die beiden Erweiterungen ja schon objekt-mäßig aufgebaut sind und beide prepared statements unterstützen, hab ich mir die mal kurz angesehen. Eigentlich gefällt mir PDO besser, mehr oo-like und ein paar coole Features (Daten aus der DB direkt in ein Zielobjekt stecken etc.), allerdings habe ich in einem englischen Forum folgendes gefunden:

    Here's something else to keep in mind: For now (PHP 5.2) the PDO library is buggy. It's full of strange bugs. For example: before storing a PDOStatement in a variable, the variable should be unset() to avoid a ton of bugs. Most of these have been fixed in PHP 5.3 and they will be released in early 2009 in PHP 5.3 which will probably have many other bugs. You should focus on using PDO for PHP 6.1 if you want a stable release and using PDO for PHP 5.3 if you want to help the community.
    Das bringt mich von meinem Favoriten PDO dann doch wieder etwas ab. Ich bin froh, wenn ich von mir selbst produzierte Bugs finde und ausmerzen kann, da brauch ich nicht noch ne weitere Fehlerquelle. Da ich auch längerfristig bei MySQL bleibe, bringt mir die Abstraktheit von PDO auch nicht viel.
    Aber es macht nunmal den moderneren und umfangreicheren Eindruck und hat echt nette Möglichkeiten.

    Was würdet ihr wählen?

    Und mal abgesehen von meiner Situation, was ist sonst so zu sagen zum Thema "mysqli vs. PDO"?

    ---

    Als letztes hab ich noch eine Frage zum Thema Sicherheit: ganz egal ob ich nun mysqlis oder PDOs prepared statements verwende, auf was muss noch achten, bevor eine Usereingabe in die DB geschickt wird?

    Vor Injections dürfte ich nun geschützt sein, soll trotzdem noch eine manuelle Überprüfung stattfinden? Falls ja, wie? Denn mysql_real_escape_string funktioniert ja logischerweise nicht, zumindest nicht bei PDO.

    htmlspecialchars und htmlenities gibts noch, reicht ersteres? Ich denke, vor allem JavaScript in der DB sollte vermieden werden, HTML bei Usereingaben lieber auch.

    Sonst noch was zu beachten?


    Danke, Gruß

  • #2
    Ich nutze in meinen Projekten PDO und mir ist ehrlich gesagt nur ein Bug mit einer zu alten Mysql-Clientversion bekannt, welcher bei mehreren aktiven Select-Statements auftritt. Darum würde ich einfach mal behaupten das du mit sauberer Programmierung irgendeinen unset-vor-Benutzung-Bug nicht bemerken wirst. Allerdings programmiere ich ausdrücklich Datenbankunabhängig, weswegen mysqli direkt ausscheidet.

    Zu deiner Contentbereinigung. Injections sind mit PDO nicht mehr so möglich, wenn du mit den bind*-Methoden arbeitest. Wie du JavaScript oder komplett HTML aus Inhalten entfernst hat aber erstmal nichts mit der Datenbank zu tun. Für einfachste Bereinigungen reicht zum Beispiel strip_tags. htmlspecialchars genügt, wird aber erst vor der Contentausgabe auf die Daten angewandt. In der Datenbank müssen die Rohdaten liegen bleiben!

    Kommentar


    • #3
      Okay, danke mal soweit. Dann hoffe ich, dass mich die Käfer in Ruhe lassen und setze auf PDO.

      Aber nochmal zur Contentbereinigung und der Reihenfolge, da hab ich echt die Übersicht verloren:

      Also die manuelle Überprüfung auf SQL-Sachen fällt komplett weg, soweit, so gut.

      Fehlen noch Javascript und eventuell HTML (wobei letzteres ja eher harmlos sein sollte, oder?)

      Stellt sich die Frage, ob strip_tags, htmlspecialchars oder htmlenities am sinnvollsten dafür ist. strip_tags löscht ja wirklich, während die anderen beiden nur ersetzen. Nennt sich ein User bei der Anmeldung also

      <script type="text/javascript">alert("XSS");</script>

      so würde er mit strip_tags "alert("XSS");" heißen und bei enities seinen ganzen Namen behalten dürfen, allerdings entsprechend maskiert? Das ist dann wohl Geschmackssache denk ich mal...

      Worin liegt eigentlich der Grund, die Rohdaten unbehandelt in die DB zu schreiben und erst bei der Ausgabe zu maskieren?

      Kommentar


      • #4
        Man maskiert immer anders, abhängig davon was man wie ausgeben will.

        Kommentar


        • #5
          Ich habe ab und an auch mit anderen DBMS zu tun, also nicht nur mit MySQL. PDO kann sie alle. Aber es abstrahiert mir nicht weit genug. Prepared Statements werden emuliert, wenn es das DBMS von Hause nicht kann. Aber bei LIMIT klemmts dann schon.
          Also nutze ich Doctrine. Und von heftigen Problemen habe ich weder gehört, noch sie selber spüren müssen.
          Wir werden alle sterben

          Kommentar


          • #6
            Zitat von INC. Beitrag anzeigen
            Okay, danke mal soweit. Dann hoffe ich, dass mich die Käfer in Ruhe lassen und setze auf PDO.

            Fehlen noch Javascript und eventuell HTML (wobei letzteres ja eher harmlos sein sollte, oder?)
            Nein, ist es nicht. Fehlerhaftes HTML ist ja gerade der Einfallspunkt für Javascript-Code-Injections. Und es gibt, dank des unermesslichen Einfallsreichtums der Browser-Hersteller und auch der Entwickler des MSIE, eine Unzahl von Möglichkeiten, irgendwo in HTML und auch CSS Befehle zum Ausführen von Scripts einzuschmuggeln.
            Stellt sich die Frage, ob strip_tags, htmlspecialchars oder htmlenities am sinnvollsten dafür ist.
            Ganz einfach: Nimm htmlspecialchars($raw, ENT_QUOTES) mit sonst keiner weiteren Option. Bspq. den UTF-8-Mode einzustellen, verdoppelt nur die Laufzeit, ändert aber ansonsten nichts.

            Die anderen Funktionen sind für die Tonne.

            Übrigens sollte htmlspecialchars() auch bei den Daten angewendet werden, die in Attribut-Werte eingetragen werden, wie beispielsweise bei Links das href-Attribut.

            Nennt sich ein User bei der Anmeldung also

            <script type="text/javascript">alert("XSS");</script>

            so würde er mit strip_tags "alert("XSS");" heißen und bei enities seinen ganzen Namen behalten dürfen, allerdings entsprechend maskiert? Das ist dann wohl Geschmackssache denk ich mal...
            Bei Nutzung von htmlspecialchars() würde er diesen Namen behalten dürfen. Und das ist nicht Geschmackssache, sondern Erhaltung der eingegebenen Daten, statt Verstümmelung (wie bspw. mit strip_tags()). Wenn ich in irgendein Webformular was eingebe, dann erwarte ich, dass das verarbeitende Script das so speichert und nichts davon kaputtmacht, nur weil der Programmierer zu dusselig war und seine Grundlagen nicht kapiert hat.

            Worin liegt eigentlich der Grund, die Rohdaten unbehandelt in die DB zu schreiben und erst bei der Ausgabe zu maskieren?
            Weil sie so in Originalform erhalten bleiben und die Datenbank eben nicht für HTML-JavaScript-Code-Injections anfällig ist.

            Für Datenbanken reicht die passende Escaping-Funktion.

            http://xkcd.com/327/
            Zuletzt geändert von fireweasel; 07.06.2009, 23:37.
            Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

            Kommentar

            Lädt...
            X