Programmierung

Datenbank-Sicherheit mit Prepared Statements

(2 Bewertungen, Durchschnitt 5.00 von 5)
Prepared Statements mit PDO eignen sich um Datenbank-Sicherheit für PHP zu gewährleisten.

Datenbank-Sicherheit, insbesondere im Zusammenhang mit sogennanten SQL-Injections (Fremdangriffe durch Hacker) ist immer wieder ein Thema für Web-Programmierer. Als ein probates Mittel dagegen haben sich Prepared Statements erwiesen. Nun bietet auch PHP in neueren Versionen diese Funktionalität.


Relativ problemlos läßt sich mit PHP ab 5.1 mit Prepared Statements arbeiten. Versionen davor sind entweder garnicht in der Lage oder aber mit erheblichem Mehraufwand und Installation. Unversierte Nutzer kann das auch mal schnell überfordern.



Dreh- und Angelpunkt ist das sogenannte PDO-Modul, welches gebraucht wird.


mit


<?php

    phpinfo();

?>


läßt sich zügig ermitteln, ob es vorhanden ist. In der Ausgabe sollte z.B. sowas zu finden sein:


PDO

PDO support enabled

PDO drivers mssql, mysql, sqlite2


und ungefähr sowas, wenn man mysql nutzt:


pdo_mysql

PDO Driver for MySQL, client library version 5.0.21


Nun zum Quelltext, wie man PDO sinnvoll nutzen kann:


<?php

try {

    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);

    $stmt = $dbh->prepare("SELECT * FROM tabelle WHERE vorname = :vorname AND nachname = :nachname");

    $stmt->bindParam(':vorname', "Hans");

    $stmt->bindParam(':nachname', "Meier");


    if ($stmt->execute()) {

        while ($row = $stmt->fetch()) {

            print_r($row['vorname']);

        }

    }


    $dbh = null;

} catch (PDOException $e) {

    print "Error!: " . $e->getMessage() . "<br/>";

    die();

}

?>


try-catch: Für Java-Enwickler nichts Neues, für manchen PHP-Entwickler schon. Man nennt es auch Exception-Handling, denn im Falle eines Fehlers kann man das weitere Verhalten explizit sehr komfortabel bestimmen. Der catch-Block fängt den Fehler quasi ab, die darin enthaltenen Anweisungen werden dann ausgeführt.


$dbh = new PDO('mysql:... Die Verbindung zur Datenbank wird aufgebaut. (hier mysql)

$stmt = $dbh->prepare... Die Abfrage wird vorbereitet, "präpariert".

$stmt->bindParam... Die Parameter werden ans Statement gegeben.

$stmt->execute(); Die Abfrage wird ausgeführt.

while ($row = $stmt->fetch()) Die Ergebnismenge wird zeilenweise abgearbeitet.

$dbh = null; Die Verbindung wird geschlossen.


Was auch geht:


$stmt = $dbh->prepare("SELECT * FROM tabelle WHERE vorname = ? AND nachname = ?");

$stmt->bindParam(1, "Hans");

$stmt->bindParam(2, "Meier");


Ich sehe keinen expliziten Vorteil für das eine oder andere, würde mich über eine Belehrung freuen.

Kommentare  

 
+1 # Herr Agel 2010-09-07 17:29
Zur Wahl der Alternativen [keine Belehrung, bloß eine Meinung]:

Ich nehme Tor 1 und bitte jeden Entwickler, Variante 2 der Parameterbindun g nach Möglichkeit nicht zu benutzen.

Grund: durch explizite Benennung ist der Quellcode deutlich lesbarer und somit auch langfristig leichter zu warten.

Bei Anweisungen wie
$stmt->bindParam(14, "foo");
das vierzehnte Fragezeichen aus der Abfrage herauszusuchen, ist halt doch eher ermüdend.

Und mehr noch: man stelle sich Abfrage mit mehreren Parametern ( > 10 etwa) vor. Sollte es nun nötig sein, an dritter Stelle einen weiteren Parameter einzufügen, so muss die Nummerierung aller folgenden Parameter aktualisiert werden - ein Aufwand, der sich bei der benannten Variante nicht ergibt, hier muss nur eine neue Bezeichnung erdacht werden.

So long,

Michael
Antworten | Antworten mit Zitat | Zitieren
 

Kommentar schreiben


Sicherheitscode
Aktualisieren