2.8) SQL-Datenbankzugriff mit PHP

Um auf eine MySQL-Datenbank zuzugreifen, muss zuerst eine Verbindung (mysqli_connect) hergestellt werden. Dazu ist der Host, auf dem der MySQL-Server läuft, der Benutzername sowie das Kennwort anzugeben. Anschließend muss noch eine Datenbank auf dem DBS ausgewählt werden (mysqli_select_db). Danach können die SQL-Anweisungen folgen (mysqli_query). Im Falle einer SQL-Abfrage liefert diese Funktion alle Tupel zurück, welche der Reihe nach mit mysqli_fetch_array abgearbeitet werden können.

Im Folgenden soll als Beispiel ein Gästebuch realisiert werden. Dazu wurde eine Tabelle meldung erstellt, welche die einzelnen Nachrichten aufnehmen soll:

CREATE TABLE meldung (
  id INT NOT NULL AUTO_INCREMENT,
  datum DATETIME DEFAULT NULL,
  name VARCHAR(200) DEFAULT NULL,
  eintrag TEXT,
  CONSTRAINT PK_id PRIMARY KEY (id)
);

Zusätzlich zu den Daten datum, name und eintrag wurde ein Attribut id eingeführt, welches als Schlüssel dient.

Das folgende Skript show.php liest alle Einträge der Datenbank aus und gibt sie in Tabellenform aus:

<?php
	$DBHost = "127.0.0.1";
	$DBUser = "root";
	$DBPasswd = "";
	$DBName = "db";
 
	//Verbindung zu DB-Server herstellen
	$con=mysqli_connect($DBHost, $DBUser, $DBPasswd, $DBName)
	  OR die("Konnte DB-Server nicht erreichen!");
	mysqli_select_db($con,$DBName);
?>
<html>
	<head>
		<title>Alle Meldungen</title>
	</head>
	<body>
	<?php
		$erg=mysqli_query($con, "SELECT datum, name, eintrag FROM meldung ORDER BY datum DESC");
		echo mysqli_error($con);
 
		while($row=mysqli_fetch_array($erg))
		{
			echo "<table bgcolor=\"#dddddd\" border=\"0\" width=\"600\"> \n";
			echo "<tr><td>Datum: </td><td>".$row["datum"]."</td></tr> \n";
			echo "<tr><td>Name:</td><td>" .$row ["name"]. "</td></tr> \n";
			echo "<tr><td valign=\"top\">Eintrag:</td> \n";
			echo "<td>".nl2br(htmlentities($row["eintrag"]))."</td></tr> \n";
			echo "</table>\n<br>\n";
		}
	?>
	<hr><a href="insert.php">neuen Eintrag hinzufügen</a>
	</body>
</html>

Um neue Einträge für das Gästebuch zu erstellen, existiert ein weiteres Skript insert.php:

<?php
	$DBHost = "127.0.0.1";
	$DBUser = "root";
	$DBPasswd = "";
	$DBName = "db";
 
	//Verbindung zu DB-Server herstellen
	$con=mysqli_connect($DBHost, $DBUser, $DBPasswd)
	  OR die("Konnte DB-Server nicht erreichen!");
	mysqli_select_db($con,$DBName);
?>
<html>
	<head>
		<title>Neuer Eintrag in unser Gästebuch</title>
	</head>
	<body>
		<?php
 
			if(isset($_GET["submit"]))
			{
				$submit = $_GET["submit"];
				$name = $_GET["name"];
				$eintrag = $_GET["eintrag"];
 
				//Der Submit-Button wurde gedrückt --> die Werte müssen überprüft werden
				//und bei Gültigkeit in die DB eingefügt werden
 
				$DatenOK=1;		//wir gehen prinzipiell von der Gültigkeit der Daten aus
				$error="";		//es gab noch keine Fehlermeldung bis hier hier
 
				if($name=="")	//Kein Name eingegeben
				{
					$DatenOK=0;
					$error.="Es muss ein Name eingegeben werden!<br>\n";
				}
				if($eintrag=="")	//Kein Kommentar eingegeben
				{
					$DatenOK=0;
					$error.="Ein Eintrag ohne Kommentar macht nicht viel Sinn!<br>\n";
				}
				if($DatenOK)		//Daten OK -> also in DB eintragen
				{
                                        $timestamp=date("Y-m-d h:i:s", time());
					mysqli_query($con,"INSERT INTO eintraege (datum, name, eintrag) VALUES (\"$timestamp\", \"$name\", \"$eintrag\" );");
					echo mysqli_error($con);
					echo "<b>Daten wurden eingetragen.<b>";
				}
				else
				{
					echo "<h2>Fehler: </h2>\n"; //Fehlermeldung
					echo $error;
				}
			}
 
			//Formular
		?>
 
 
 
		<form action="insert.php" method="GET">
			Name: <input type="text" name="name" size="30" maxlength="200" value=""><br>
			Text: <br><textarea rows="10" cols="50" wrap="virtual" name="eintrag"></textarea>
			<br><input type="submit" name="submit" value="Absenden">
		</form>
		<a href="show.php"> Alle Einträge anzeigen</a>
	</body>
</html>

SQL Injection

SQL injection ist eine Einschleusung von Code der die Datenbank möglicherweise zerstört

SQL injection ist eine von den meist genutzten Hacking Methoden

SQL injection bezeichnet das Einschleusen von bösartigen Code in die SQL-Statements mithilfe von Formulardaten in Webseiten

SQL Injection basierend auf 1=1 ist immer wahr (true)

Nehmen wir an, es soll innerhalb einer Webseite die UserId angegeben werden, um die jeweiligen Informationen des Users auszugeben.
Ist diese Eingabe nicht beschränkt, so kann der Benutzer eingeben was er will. Füllt er diese Eingabe „intelligent“ aus, so kann er die ursprüngliche Funktion des SQL-Statements vollkommen verändern.
z.B.:

Dadurch wird das SQL-Statement wie folgt verändert:

SELECT * FROM Users WHERE UserId = 105 OR 1=1;

Somit wird dieses SQL-Statement alle Zeilen der Tabelle Users zurückgeben, da ja OR 1=1 immer erfüllt ist.
Das wäre besonders heikel, falls die Users Tabelle Benutzernamen & Passwörter beinhaltet. Dann würde das manipulierte SQL-Statement dasselbe verursachen wie folgendes SQL-Statement:

SELECT UserID, Name, Passowrd FROM Users WHERE UserId=105 OR 1=1

Durch diese Manipulation würde der Hacker Zugriff zu allen Benutzernamen und Passwörter in der Datenbank erlangen, durch einfaches hinzufügen von OR 1=1.