Dennis: Sichern einer MySQL-Datenbank in PHP

Beitrag lesen

Hi dedlfix,

Es ist aber schlicht egal, an welcher Stelle du nicht damit rechnest, dass so etwas passieren könnte. […]

Ja, das sehe ich ein - deshalb auch mein anschließendes

das Script sollte natürlich so oder so sicher sein

Gut erkannt. Es ist aber nicht deine Aufgabe für die Richtigkeit der übergebenen Parameter zu sorgen. Du hast sie nur unbeschadet ans Ziel zu bringen oder mit Fehlermeldungen um dich zu werfen, wenn das nicht geht.

Nehmen wir einmal an, es geht um folgenden String: foo " bar.

Durch magic_quotes wurde da bereits ein Slashs vor das Anführungszeichen gesetzt, nun wende ich mysql_real_escape_string() an und daraus wird: foo \" bar - ich habe damit also soeben eine Sicherheitslücke geöffnet.

An der Stelle frage ich mich eben, was besser ist - und muss sagen, dass ich keine Ahnung habe…

Man muss nicht alle Dummheiten der Anwender korrigieren wollen, man muss nur dafür sorgen, dass sie keinen Schaden anrichten.

…dieser Satz gefällt mir aber sehr gut ;-) Ich denke mal, dass ich dann einfach mysql_real_escape_sring() anwenden werde - es ist dann Sache des Users dafür zu sorgen, dass die Strings nicht bereits escaped sind.

Hin- und Hermaskierungen mitten in der Verarbeitung tragen nicht grade zur Übersichtlichkeit des Prozesses bei.

Dito.

Alle Stellen zu denen unmaskierte Daten gelangen können sind anfällig. Aus deiner Sicht magst du alle (dir bekannten) Angriffsmöglichkeiten als nicht zielführend bewertet haben, und trotzdem hast du die eine Möglichkeit übersehen, bei der es passieren kann.

Stimmt - aber da kommt noch eine Frage auf: ist mysql_real_escape_string() auch dafür gedacht, auf Tabellennamen angewendet zu werden? Ich habe es bis jetzt immer mehr dafür gehalten, es auf quotierte Strings anzuwenden.

Bei einem Tabellennamen wäre ja wichtig, dass mysql_real_escape_string() auch die escaped, also zu \ macht - ich werde mal testen müssen, ob dem so ist - wenn dem nicht so ist, würde der String
  tabelle; DELETE FROM tabelle
eingefügt in
  SELECT * FROM [code lang=php]$string{:.language-sql}[/code]
immer noch zu
  SELECT * FROM tabelle; DELETE FROM tabelle``
werden und damit Schaden anrichten.

Nun, man kann export_table_data() auch zu Fuß aufrufen. PHP4 sei Dank (oder auch nicht) sind ja alle Methoden public.

Eher „oder auch nicht“ - einer der Gründe, weshalb ich OOP in PHP4 nicht mag, wenn schon OOP, dann auch richtig.

var $newline = "\n";
Ich würde keine Klassenvariable dafür verwenden, zumal es außer einer Quelltextänderung keine Möglichkeit gibt, die zu verändern.

Doch, dank PHP4 kannst du folgendes machen:

$instanz = new MySQLDBExport();  
$instanz->newline = "\r\n";

Die Variable war eigentlich so gedacht, dass sie als public definiert werden sollte, aber… Du weißt schon ;-)

Mein Vorschlag wäre eine Konstante zu definieren, falls sie noch nicht anderswo gesetzt wurde.

Konstanten mag ich deshalb nicht so, weil diese „superglobal“ sind - also überall gelten - vielleicht möchte ja jemand nach mir im Script noch NEWLINE definieren.

O.K. Der Anwender kann die Eigenschaft nach erfolgter Instantiierung ändern. Dazu muss er aber voraussetzen, dass sie bis dahin noch nicht verwendet wurde. (Die Analyse des Konstruktor-Quelltexts, um das herauszufinden, ist keine sehr feine Option.)

Das verstehe ich nicht ganz - nach der Instantiierung lässt sich $newline ändern wie ich oben gezeigt habe, wolltest du das sagen? Dann verstehe ich aber den nachfolgenden Satz nicht…

Alternativ wäre auch noch ein weiter optionaler Konstruktor-Parameter denkbar.

Das ist die Methode, die mir am besten gefällt - oder eventuell noch eine weitere Funktion set_newline($newline).

Die Zwischenvariable $con in Zeile 77 ff. ist nicht nötig. Du kannst gleich $this->con verwenden.

Stimmt, danke.

Teilweise gibt es Ansätze, das Ergebnis variieren zu können (z.B. Parameter $drop_if_exists für Methode export_table_structure(), Zeile 126). Beim Aufruf der Methode (Zeile 251) wird dann aber ein fest vorgegebener Wert verwendet. Da gibt es also noch Erweiterungspotential für die Klasse. :-)

Ja, da hast du Recht ;-) Wobei ich es mir als ich damit angefangen habe eben so gedacht habe, dass es die Einzel-Funktionen gibt - wer alles selber festlegen will, soll diese Einzelfunktionen nutzen, make_dump() sollte dann ein Interface sein, dass auch mit DAU-Kenntnissen zu nutzen ist.

false (Zeilen 138 und 157) ist kein wirklich geeigneter Wert, um einen String zu erweitern (Zeile 251f.) Außerdem sagt make_dump() in dem Fall, dass alles in Ordnung wäre. Nur das Ergebnis ist dann nicht wie vom Anwender erwartet ...

Stimmt, auch da sollte man noch etwas dran arbeiten - vielleicht gibt das dann zusammen mit ein paar neuen Funktionen und Funktionsparametern eine ganz neue Klasse - Version 3.0 ;-)

Das sind nur Dinge, die mir beim Drüberschauen aufgefallen sind. Die Klasse einmal anzuwenden habe ich nicht versucht.

Ich danke dir auf jeden Fall sehr für das Drüberschauen - den eigenen Quellcode auf Fehler zu untersuchen ist finde ich stets schwerer bzw. darin Fehler zu finden ist schwerer als dies beim Quellcode von anderen Leuten zu tun.

MfG, Dennis.