Zentrum für Informationsdienste und Hochleistungsrechnen (ZIH) PHP und MySQL Integration von MySQL in PHP Zellescher Weg 12 Willers-Bau A109 Tel. +49 351 - 463 - 32424 Michael Kluge ([email protected]) MySQL – Themenüberlick Verbindung zur Datenbank herstellen Daten aus Datenbank abrufen Daten in die Datenbank schreiben Arbeit mit mehreren Tabellen Struktur der Datenbank auslesen Sicherheitsaspekte bei der Datenbankarbeit Ein kleines Beispiel Michael Kluge MySQL – Verbindungsaufbau Verbindung zum Server wird Beginn der Sitzung geöffnet Verbindung sollte am Ende der Sitzung geschloßen werden <?php $link = mysql_connect('localhost', 'zih01', 'zih01'); if (!$link) { die('Verbindungsfehler: ' . mysql_error()); } echo 'Connected successfully'; mysql_close($link); ?> Michael Kluge MySQL – Datenbankabfragen Prinzipiell ist jedes SQL-Query über mysql_db_query und mysql_query nutzbar. Werden Daten abgerufen kann der Rückgabewert mit mysql_fetch_... ausgewertet werden. Bei schreibenden SQL-Querys wird bei Erfolg TRUE und bei Misserfolg FALSE zurückgegeben. Datenbankserver Datenbank 1 Tabelle Tabelle Michael Kluge Tabelle Datenbank 2 Tabelle Tabelle Tabelle Tabelle MySQL – Datenabfragen <?php // abfrage auf explizite datenbank $result = mysql_db_query( 'db_zih_01', 'select * from demo' ); while( $row = mysql_fetch_row( $result ) ) { var_dump( $row ); } // abfrage auf ausgewählte datenbank if( !mysql_select_db('db_zih_01') ) { die ('Fehler beim Zugriff auf db_zih_01 : ' . mysql_error()); } $result = mysql_query( 'select * from demo' ); while( $row = mysql_fetch_row( $result ) ) { var_dump( $row ); } ?> Michael Kluge MySQL – Daten auswerten als Array <?php $result = mysql_query( 'select * from demo' ); while( $row = mysql_fetch_row( $result ) ) { // dump der daten var_dump( $row ); // zugriff auf daten echo $row[0]; echo $row[1]; } ?> array(2) { [0]=> string(1) "1" [1]=> string(17) "Der erste Eintrag" } array(2) { [0]=> string(1) "2" [1]=> string(18) "Der zweite Eintrag" } Michael Kluge MySQL – Daten auswerten als Assoziatives-Array <?php $result = mysql_query( 'select * from demo' ); while( $row = mysql_fetch_assoc( $result ) ) { // dump der daten var_dump( $row ); // zugriff auf daten echo $row['demo_id']; echo $row['demo_data']; } ?> array(2) { ["demo_id"]=> string(1) "1" ["demo_data"]=> string(17) "Der erste Eintrag" } array(2) { ["demo_id"]=> string(1) "2" ["demo_data"]=> string(18) "Der zweite Eintrag" } Michael Kluge MySQL – Daten auswerten als Gemischtes-Array <?php $result = mysql_query( 'select * from demo' ); while( $row = mysql_fetch_array( $result ) ) { // dump der daten var_dump( $row ); // zugriff auf daten echo $row['demo_id']; echo $row['demo_data']; // alternativer zugriff echo $row[0]; echo $row[1]; } ?> array(4) { [0]=> string(1) "1" ["demo_id"]=> string(1) "1" [1]=> string(17) "Der erste Eintrag" ["demo_data"]=> string(17) "Der erste Eintrag" } Michael Kluge MySQL – Daten auswerten als Daten-Objekt <?php $result = mysql_query( 'select * from demo' ); while( $row = mysql_fetch_object( $result ) ) { // dump der daten var_dump( $row ); // zugriff auf daten echo $row->demo_id; echo $row->demo_data; } ?> object(stdClass)(2) { ["demo_id"]=> string(1) "1" ["demo_data"]=> string(17) "Der erste Eintrag" } object(stdClass)(2) { ["demo_id"]=> string(1) "2" ["demo_data"]=> string(18) "Der zweite Eintrag" } Michael Kluge MySQL – Schreiben in Tabellen <?php // einfügen von datensätzen auf explizite datenbank $query = 'insert into demo demo_date (values) “Ein Test”'; if( !mysql_query( $query ) ) { echo 'Fehler beim Schreiben in Tabelle demo:' . mysql_error(); } // aktualisieren von datensätzen $query = 'update demo set demo_date=”Wert” where demo_id=3'; if( !mysql_query( $query ) ) { echo 'Fehler beim Schreiben in Tabelle demo:' . mysql_error(); } ?> Michael Kluge MySQL – Löschen aus Tabellen <?php // löschen einzenler datensätze $query = 'delete from demo where demo_id=3'; if( !mysql_query( $query ) ) { echo 'Fehler beim Löschen aus Tabelle demo:' . mysql_error(); } // löschen einer ganzen tabelle mit optimize $query = 'truncate table demo'; if( !mysql_query( $query ) ) { echo 'Fehler beim Löschen aus Tabelle demo:' . mysql_error(); } ?> Michael Kluge MySQL – Nützliche PHP-Funktionen <?php // anzeige der betroffenen zeilen $query = 'delete from demo where demo_id > 3'; mysql_query( $query ); echo 'Es wurden '. mysql_affected_rows() .' gelöscht'; // ausgabe des letzten primärschlüssels mysql_query( 'insert into tbl1 data (values) “wert“' ); $last_id = mysql_insert_id(); mysql_query( 'insert into tbl2 fk_demo (values)'. $last_id ); ?> Michael Kluge MySQL – SQL-Injection Interaktive Webanwendungen übertragen Daten vom Client zum Server SQL-Injection = Modifikation eines übertragenen Wertes um zusätzliche Steuerbefehle auszuführen Grund für Anfälligkeiten = mangelhafte Typ/Inhaltsprüfung vor weitergabe an die Datenbank Michael Kluge MySQL – SQL-Injection – potentielle Ziele Steuerkommandos SELECT INTO OUTFILE ("/etc/passwd") EXEC Informationslecks SELECT * FROM v$version (Oracle) SELECT * FROM sysdatabases (MSSQL) SELECT VERSION() (MySQL) Zugriff auf gesicherte Bereiche Auslesen von Kundendaten aus Tabellen Michael Kluge MySQL – SQL-Injection – Beispiel Loginformular auf einer Webseite Benutzer muss Name und Passwort eingeben SQL-Abfrage zur Prüfung: “select * from users where user='“.$_GET['user'].“' and pass='”.$_GET['passwort']; Angreifer gibt als Benutzer john '-- ein select * from users where user='john' Angreifer gibt als Benutzer john' or '1'='1 select * from users where user='john' or '1'='1' and pass='12345' Michael Kluge MySQL – SQL-Injection Abwehr Alle Nutzereingaben prüfen – Eingaben prüfen (Datentypen/Werte) – filtern von Sonderzeichen " ' ; \ - (z.B. mysql_real_escape_string) Verwenden von mod_security – Serverseitige Applikation-Level Firewall – filtert automatisch SQL-Injections Michael Kluge MySQL – Beispiel – Nutzerdatenbank $link = mysql_connect('localhost', 'zih01', 'zih01'); mysql_select_db( zih_db_01 ); if( !mysql_query( 'show columns from nutzer_db' ) ) { $create_query = “CREATE TABLE nutzer_db( nutzer_id int AUTO_INCREMENT PRIMARY KEY , name varchar( 128 ) , pass varchar( 32 ) )“; mysql_query( $create_query ); } mysql_close( $link ); Michael Kluge MySQL – Beispiel – Nutzerdatenbank $link = mysql_connect('localhost', 'zih01', 'zih01'); mysql_select_db( zih_db_01 ); $sql = “insert into nutzer name, pass (values) 'hans','”.md5('test')“.'“; mysql_query( $sql ); $sql = “insert into nutzer name, pass (values) 'maus','”.md5('tset')“.'“; mysql_query( $sql ); $sql = “insert into nutzer name, pass (values) 'meier','”.md5('reiem')“.'“; mysql_query( $sql ); mysql_close( $link ); Michael Kluge MySQL – Beispiel – Nutzerdatenbank $link = mysql_connect('localhost', 'zih01', 'zih01'); mysql_select_db( zih_db_01 ); $sql = “select * from nutzer where name='”.$_REQUEST['user'].”' and pass='“.md5( $_REQUEST['pass'] ).“'“; mysql_query( $sql ); if( mysql_affected_rows == 1 ) { echo „willkommen“ } else { // anzeige des html formulars } mysql_close( $link ); Michael Kluge