Registrieren  •  Login 
  
 
im Forum


 FAQ   Mitgliederliste   Benutzergruppen   Teamseite   Suchen 

[Anleitung] Datenbanken (z.B: MySQL, MSSQL, PostgreSQL, ...)

 
Neues Thema eröffnen   Neue Antwort erstellen
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
killerbees19
Administrator & Rennleitung
Administrator & Rennleitung



OC-Nickname: KB19
Südafrika Team South Africa

Anmeldedatum: 09.05.2006
Geschlecht: Männlich
Alter: 29 Jahre
Beiträge: 13952
Wohnort: Wien

BeitragVerfasst am: 28.05.2008, 19:56    Titel: [Anleitung] Datenbanken (z.B: MySQL, MSSQL, PostgreSQL, ...)

Egal mit welcher Programmiersprache, irgendwann braucht sie jeder: Datenbanken. Und egal ob man jetzt MySQL, MSSQL oder PostgreSQL verwendet, eines ist überall gleich: Nutzereingaben müssen hier maskiert werden, ansonsten hat man gleich ein perfektes Sicherheitsleck, das man "SQL Injection" nennt. In meinen Beispielen beziehe ich mich hauptsächlich auf PHP & MYSQL. Bei anderen DBMS bzw. Programmiersprachen ist es aber fast immer ähnlich. Zwei Dinge muss ich einmal jedem ans Herz legen: Zur einfacheren Verwaltung sollte man immer eine Datenbankklasse benutzen. Diese Möglichkeit hat PHP seit der Version 5 sogar On-Board mit den MySQLi (das i am Ende nicht überlesen) Funktionen. Der zweite Hinweis ist eigentlich ziemlich allgemein gehalten: Nach dem Verbindungsaufbau zu MySQL ist es immer empfehlenswert, wenn man das Datenbankpasswort löscht, das heißt, man soll Variablen in denen es gespeichert ist an unset() übergeben.

Im folgenden Code sieht man ein kurzes Script, das eine Verbindung zu MySQL herstellt (ich habe zum einfacheren Verständnis die "normalen" MySQL Funktionen benutzt). An diesem Beispielscript werde ich im folgenden Beitrag immer wieder anschließen.
PHP-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php

// Zugangsdaten
$server   'localhost';
$username 'happytec';
$password '0123456';
$dbname   'xyz';

// Verbindung herstellen
$db_id mysql_connect($server$username$password);
if(!
is_ressource($db_id))
{
    die(
'Verbindungsfehler zur Datenbank!');
}

// Passwort löschen
unset($password);

// Datenbank auswählen
if(!mysql_select_db($dbname$db_id))
{
    die(
'Konnte die Datenbank nicht auswählen!');
}

################################################################################



################################################################################

// Verbindung schließen
mysql_close($db_id);

?>


Der Standardfehler, den viele User machen, ist wohl, dass sie einfach Nutzereingaben ungeprüft an MySQL übergeben. Im folgenden Code wird eine Sicherheitslücke demonstriert, die einem Angreifer alles mögliche erlauben würde.
PHP-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

// Das ist ein Sicherheitsleck: So soll man es nicht machen!
$sql "SELECT * FROM `demo_table`
        WHERE id = " 
$_GET['id'];
$result mysql_query($sql$db_id);
if(!
$result)
{
    echo 
'SQL Error '.mysql_errno($db_id).': '.htmlspecialchars(mysql_error($db_id)).'<br />'.htmlspecialchars($sql);
    exit;
}

?>

Da hier die Nutzereingabe ungeprüft übernommen wird, könnte der Angreifer jeden beliebigen Code ausführen. Deshalb muss man Daten die man an eine Datenbank übergibt immer mit mysql_real_escape_string() behandeln, oder wie in diesem Beispiel mit intval(), da es sich hierbei nur um eine Zahl handelt. Aber auch bei reinen Zahlen sollte man immer überprüfen, ob es sich auch um eine gewünschte handelt. Denn bei MySQL können negative Zahlen zum Beispiel einen Fehler auslösen. Deshalb hier noch ein Beispiel, in dem wir nur eine positive Zahl erwarten.
PHP-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

// Noch bessere Methode
$id intval($_GET['id']);
$id = ($id 0) ? $id;
$sql "SELECT * FROM `demo_table`
        WHERE id = " 
$id;
$result mysql_query($sql$db_id);
if(!
$result)
{
    echo 
'SQL Error '.mysql_errno($db_id).': '.htmlspecialchars(mysql_error($db_id)).'<br />'.htmlspecialchars($sql);
    exit;
}

?>

Zur Erklärung für Einsteiger: Die 5. Zeile ist hier eine verkürzte IF-ELSE-Schreibweise. Im nächsten Beispiel zeige ich noch die Verwendung von mysql_real_escape_string(). Diese Funktion brauchen wir bei allen anderen Eingaben. Wichtig: Nicht die internen Anführungszeichen für MySQL vergessen!
PHP-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

// Verwendung von mysql_real_escape_string()
$sql "SELECT * FROM `demo_table`
        WHERE username = '" 
mysql_real_escape_string($_POST['username'], $db_id)."'";
$result mysql_query($sql$db_id);
if(!
$result)
{
    echo 
'SQL Error '.mysql_errno($db_id).': '.htmlspecialchars(mysql_error($db_id)).'<br />'.htmlspecialchars($sql);
    exit;
}

?>

Die Verwendung ist also ziemlich einfach, man darf nur nicht darauf vergessen. Denn genau wegen solchen Fehlern wurden selbst die größten Websites bereits gehackt.

Der nächste Punkt betrifft die MySQL Funktion LIKE. Wie manche vielleicht wissen, verwendet man LIKE für einfache Suchen, Jokerzeichen werden dabei auch unterstützt. Und genau diese Jokerzeichen sollte man vorher maskieren. Jokerzeichen sind in diesem Fall das Prozentzeichen und der Unterstrich. Mit der folgenden Funktion kann man diese Zeichen sehr leicht markieren und auch gleich mysql_real_escape_string() anwenden.
PHP-Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

// Funktion zum Vorbereiten von MySQL Strings
function mysql_prepare($string$like false)
{
    if(
$like)
    {
        return 
mysql_real_escape_string(str_replace(array('%''_'), array('\\%''\\_'), $string));
    }
    else
    {
        return 
mysql_real_escape_string($string);
    }
}

// Richtige Verwendung bei LIKE
$sql "SELECT * FROM `demo_table`
        WHERE username LIKE '" 
mysql_prepare($_POST['username'], true)."'";
$result mysql_query($sql$db_id);
if(!
$result)
{
    echo 
'SQL Error '.mysql_errno($db_id).': '.htmlspecialchars(mysql_error($db_id)).'<br />'.htmlspecialchars($sql);
    exit;
}

?>

Hier wird also die zuvor definierte Funktion mysql_prepare() aufgerufen und der zweite Parameter auf true gesetzt, wodurch auch alle Jokerzeichen für LIKE maskiert werden.

mysql_real_escape_string() ähnelt außerdem sehr der bekannten Funktion addslashes(). Man sollte jedoch trotzdem immer mysql_real_escape_string() verwenden, da nur diese Funktion wirklich alle gefährlichen Zeichen maskiert! In PHP gibt bzw. gab es außerdem die Magic Quotes Funktionalität, welche alle Eingabedaten des Users (sprich $_POST, $_GET und $_COOKIE z.B.) automatisch mit addslashes() behandelt. Da diese Funktion jedoch in PHP 6 entfernt werden wird, sollte man sich auf diese Funktion nicht mehr verlassen und sie somit nicht mehr verwenden. Die manuelle Verwendung von mysql_real_escape_string() eignet sich auf jeden Fall besser. Zu erwähnen ist auch noch, dass man wirkliche alle Daten (die man in eine Datenbank einträgt) auf diese Weise maskieren muss! Für weitere Informationen empfehle ich noch einen Blick in das PHP Handbuch, das ich in diesem Beitrag mehrmals verlinkt habe.

Bei Fragen oder weiteren Tipps zu diesem Thema, schreibt einfach einen Beitrag in dieses Forum Wink


MfG Christian
_________________
Nach oben
Benutzer-Profile anzeigen killerbees19 ist derzeit offline Spielerprofile bei SC:Special Bewerben anzeigen Private Nachricht senden Website dieses Benutzers besuchen
rami
Mitglied
Mitglied



Anmeldedatum: 07.10.2006
Geschlecht: Männlich
Beiträge: 759

BeitragVerfasst am: 29.05.2008, 18:17    Titel: Re: [Anleitung] Datenbanken (z.B: MySQL, MSSQL, PostgreSQL,

killerbees19 hat Folgendes geschrieben:
Nutzereingaben müssen hier maskiert werden, ansonsten hat man gleich ein perfektes Sicherheitsleck, das man "SQL Injection" nennt.
Okay, ich darf auch mal Klugscheißern: SQL-Injection ist doch die Angriffsmethode nicht das Leck, oder?
Nach oben
Benutzer-Profile anzeigen rami ist derzeit offline Spielerprofile bei SC:Special Bewerben anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
killerbees19
Administrator & Rennleitung
Administrator & Rennleitung



OC-Nickname: KB19
Südafrika Team South Africa

Anmeldedatum: 09.05.2006
Geschlecht: Männlich
Alter: 29 Jahre
Beiträge: 13952
Wohnort: Wien

BeitragVerfasst am: 29.05.2008, 18:40    Titel: Re: [Anleitung] Datenbanken (z.B: MySQL, MSSQL, PostgreSQL,

rami hat Folgendes geschrieben:
Okay, ich darf auch mal Klugscheißern: SQL-Injection ist doch die Angriffsmethode nicht das Leck, oder?

Eigentlich schon, aber in diesem Zusammenhang ist es ja dann auch die Sicherheitslücke, deshalb habe ich es einmal so geschrieben. Wenn mir jemand sagen kann, wie man diese Sicherheitslücke sonst nennen sollte, ändere ich es natürlich ab. Weitere Infos über SQL Injections findet man übrigens auch in Wikipedia.


MfG Christian
_________________


Dieser Beitrag wurde insgesamt 1 mal geändert. Zuletzt von killerbees19.
Nach oben
Benutzer-Profile anzeigen killerbees19 ist derzeit offline Spielerprofile bei SC:Special Bewerben anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht teilnehmen.
Du kannst Dateien in diesem Forum nicht hochladen.
Du kannst Dateien in diesem Forum nicht herunterladen.

 

Alle Zeiten sind GMT + 2 Stunden (Sommerzeit)
Aktuelles Datum und Uhrzeit: 10.04.2020, 04:10
Nach oben
Valid HTML 4.01 Transitional
Valid CSS!
Software based on work from the phpBB-Group  •  Deutsche Übersetzung von phpBB.de

netcup - Internetdienstleistungen
 
 
[ happytec.at | forum.happytec.at | blog.happytec.at | esports.happytec.at | event.happytec.at ]