Register for your free account! | Forgot your password?

Go Back   elitepvpers > Off-Topics > Tutorials
You last visited: Today at 22:10

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Sichere Datenbankzugriffe durch Prepared Statements

Discussion on Sichere Datenbankzugriffe durch Prepared Statements within the Tutorials forum part of the Off-Topics category.

Reply
 
Old   #1
 
elite*gold: 320
Join Date: Mar 2010
Posts: 40
Received Thanks: 9
Sichere Datenbankzugriffe durch Prepared Statements

Um es gleich zu Anfang zu nennen: Ich werde als Beispiel-Programmier-Sprache PHP wählen, da es mit Abstand am häufigsten dort angewendet werden sollte. Grundsätzlich ist diese Technik auch auf andere Sprachen anwendbar.

1. Etwas Theorie
2. Praktisches
3. Schlusswort

Vorwort:

PHP hatte lange Zeit keine standardisierte Schnittstelle für Datenbanken, um auf verschiedene Datenbanksysteme zuzugreifen, musste der PHP-Entwickler sich viele verschiedene Funktionen merken.
Der Zugriff auf Datenbanken wurde auch nicht in Form einer Klasse angeboten, man für einheitlichen Zugriff auf DBMS war man gezwungen, entweder eine eigene Klasse zu schreiben oder PEAR:B bzw. PEAR::MDB2 zu verwenden.

Mit PDO wird dem Entwickler diese Arbeit nun abgenommen, er kann auch auf PEAR verzichten, was in einen kleinen Performance-Gewinn resultiert. Denn PDO sind keine Scripte sonder eine PECL-Erweiterung, welche für Unix/Linux als .so-Datei und für Windows als .dll gibt, das Parsen entfällt damit.

Im folgenden soll eine kurze Einführung in Prepared Statements mittels PDO Interesse für diese Technologie geben und Basis-Wissen darüber vermitteln.

1. Etwas Theorie

Die Datenbank ist ein wunderbares Medium, um Inhalte in eine dynamische Seite einzubinden. Leider kann dieser Datenbank-Zugriff bei unachtsamer Verwendung zu einer großen Sicherheitslücke werden.

Wir betrachten den folgenden Query, wie er vermutlich in sehr vielen (vor allem selbst-entwickelten) Webseiten zu finden sein wird:

Code:

"SELECT userid FROM users WHERE username = '$username' AND password = '$password'"

Dieses Statement ist hochgradig manipulierbar, im speziellen nennt man diese Manipulationen SQL-Injection. Es basiert auf der einfachen Tatsache, das wir als Webmaster nicht kontrollieren können, was ein Benutzer in das Eingabefeld für seinen Benutzernamen einträgt. Beispielsweise könnte er dort folgendes eintragen:

saftmeister' AND 1=1; --

Was folgendes bewirken würde:

Code:

"SELECT userid FROM users WHERE username = 'saftmeister' AND 1=1 -- ' AND password = ' '"

Wenn man weiß, das alles, was nach dem doppelten Minus-Zeichens als Kommentar angesehen wird, sucht der Query nur nach dem Benutzername, denn 1 ist immer 1.

Dieser Tatsache kann auf verschiedene Weise entgegen gewirkt werden.
- Man verwendet Filter-Techniken (mysql_real_escape_string, Reguläre Ausdrücke und ähnliches) um SQL-Injection zu verhindern.
- Man verwendet PDs

Die Anwendung von manuellen Filtertechniken führt nicht selten zu schwer lesbarem und damit auch schwer wartbarem Code.
PSs haben hier den Vorteil, die Übersichtlichkeit in einem Programm zu erhöhen. Außerdem gibt es noch den netten Nebeneffekt der geringeren Auslastung von CPU, Speicher und Bandbreite, da Queries nicht ständig neu gesendet werden müssen, um ein und die selbe Abfrage mit verschiedenen Daten als Parameter zu senden.

2. Praktisches

Um eine solches Problem in PS zu lösen, wird ein SQL-Server benötigt, der PSs unterstützt (z.B. MySQL, mindestens Version 4.1, die Schnittstelle wird MySQLi genannt), sowie eine Programmiersprache, die PSs senden kann z.B. die PDO von PHP5. Für PHP4 gibt es die Möglichkeit, eine Klasse einzubinden, um die Vorzüge von PSs zu nutzen.

Im folgenden der Code, danach die Erklärung:

Beispiel 1:

PHP Code:
$user "myuser";
$password "mypassword";

$dbc = new PDO("mysql:host=localhost;dbname=mydb"$user$password);

$sql "SELECT userid FROM users WHERE username = :username AND password = :password";
$stmt $dbc->prepare($sql);

$stmt->bindParam':username'$_POST['username'] );
$stmt->bindParam':password'$_POST['password'] );

if(
$stmt->execute())
{
  
$data $stmt->fetch(PDO::FETCH_OBJ);

  echo 
$data->userid;
}
$result null;
$stmt null;
$dbc null
Erklärung:
In der dritten Zeile wird eine Verbindung zum Datenbank-Server mittels der sog. DSN (Data Source Name), einer standardisierten Form, aufgebaut.

Zeile vier zeigt, wie ein Query zusammen gebaut wird, die Besonderheit der PSs werden hier schon sichtbar. Anstatt hier die Werte aus dem Login-Formular einzubinden, arbeitet ein PS mit Platzhaltern, an deren Stelle nach der Prüfung (weiter unten) die Werte automatisch gesetzt werden.

In der darauf folgenden Zeile 5 wird das SQL-Statement vorbereitet, das erledigt die Klassenmethode prepare() für uns. Hier passiert der ganze Trick, das Statement wird an den Server geschickt und dort einmal analysiert und zwischen gespeichert. Dieser Vorgang muss nur einmal durchgeführt werden, nicht wie bei den bekannten mysql_*-Funktionen, bei denen jeder Query einzeln gesendet wird.

Die nächsten Zeilen 6 und 7 beschreiben, wie die Platzhalter im PS mit den gewünschten Werten gefüllt werden. Außerdem filtert (escapen) der SQL-Server hier schon die bestimmten Zeichen, die unter normalen Voraussetzungen ein SQL-Injection verursachen können.

Der eigentliche Query im Cache wird nicht verändert wird. Das bedeutet, das der selbe Query mehrere Male hintereinander verwendet werden kann, ohne das ein neuer gesendet werden muss. Diese Tatsache wirkt sich darin aus, das Bandbreite gespart wird, da nicht mehrere Queries gesendet, sondern immer nur die unterschiedlichen Werte gebunden werden müssen (siehe Beispiel 2).

Zeile 8 schickt ein Signal an den SQL-Server, das der Query nun ausgeführt werden soll und ein Ergebnis erwartet wird, welches in einer Objekt-Variable gespeichert werden soll. Dabei handelt es sich um die komplette Ergebnismenge des Queries nicht um einen einzelnen Datensatz.

In der folgenden Zeile 9 wird nun ein Datensatz aus der Ergebnismenge geholt, was analog zum gewohnten mysql_fetch_* wäre.

Nun kann man in Zeile 10 die ausgelesenen Daten weiter verarbeiten, in diesem Beispiel werden sie ausgegeben.

Die letzten drei Zeilen dienem zum Aufräumen und Abbauen der Verbindung zum Datenbank-Server. Falls persistente Verbindungen erwünscht sind, könne diese mit dem Verbindungsflag PDO::ATTR_PERSISTENT aufgebaut werden:

PHP Code:
  <?php
$dbc 
= new PDO('mysql:host=localhost;dbname=test'$user$pass, array(
  
PDO::ATTR_PERSISTENT => true
));
?>
Beispiel 2: Verwenden des gleichen Queries für mehrere Abfragen

Wie schon oben erwähnt, brauch ein Query, der mehrere gleiche Abfragen erledigen soll, nur einmal vorbereitet werden:

PHP-Code:
PHP Code:
$customer_1 "schmidt";
$customer_2 "müller";
$customer_3 "maier";

$sql "INSERT INTO users (username) VALUES (:username)";

$stmt $dbc->prepare($sql);

$stmt->bindParam(':username'$customer_1);
$stmt->execute();

$stmt->bindParam(':username'$customer_2);
$stmt->execute();

$stmt->bindParam(':username'$customer_3);
$stmt->execute(); 
Dieser Vorgang kann natürlich auch in einer Schleife ausgeführt werden:

PHP Code:
$users = array(
  
'schmidt',
  
'müller',
  
'maier'
);

$sql "INSERT INTO users (username) VALUES (:username)";

$stmt $dbc->prepare($sql);
$stmt->bindParam(':username'$username);
foreach(
$users as $username) {
   
$stmt->execute();

Das letzte Beispiel ist schon etwas komplizierter, hier wird eine Variable an den Query gebunden. Diese Variable wird bei jedem Schleifendurchlauf mit einem neuen Wert versehen und der Query sofort ausgeführt.

3. Schlusswort

Insgesamt sehen die PS etwas komplizierter aus, als der reguläre Zugriff auf die DB, was aber täuscht, wenn man es mit komplizierten Queries zu tun hat. Hier bestechen PSs mit ihrer guten Lesbarkeit. Außerdem wird die Sicherheit enorm gesteigert, man kann einfach nicht mehr vergessen, Zeichen zu escapen. Mit PSs werden durch die geringeren Sende-Volumen Systemresourcen gespart.

Fazit: Bei neuen Projekten immer Prepared Statements verwenden und wenn möglich, bestehende Projekte darauf umarbeiten. Der Arbeitsaufwand wird durch bessere Wartbarkeit auf jeden Fall belohnt.




Quelle:


Mfg
A7!9 is offline  
Thanks
1 User
Old 03/06/2010, 20:42   #2

 
djpromo's Avatar
 
elite*gold: 20
Join Date: Jul 2004
Posts: 5,468
Received Thanks: 1,993
Versuch mal die ganzen code abschnitte in den [PHP.] ... [/PHP] Block zu packen (ohne den . ) oder auf das PHP symbol klicken , macht das ganze viel übersichtlicher

sieht dann so aus :

PHP Code:
$customer_1 "schmidt";
$customer_2 "müller";
$customer_3 "maier";

$sql "INSERT INTO users (username) VALUES (:username)";

$stmt $dbc->prepare($sql);

$stmt->bindParam(':username'$customer_1);
$stmt->execute();

$stmt->bindParam(':username'$customer_2);
$stmt->execute();

$stmt->bindParam(':username'$customer_3);
$stmt->execute(); 
djpromo is offline  
Old 03/06/2010, 20:43   #3
 
elite*gold: 320
Join Date: Mar 2010
Posts: 40
Received Thanks: 9
Gemacht
A7!9 is offline  
Old 03/06/2010, 22:22   #4
 
Pand0r's Avatar
 
elite*gold: 1438
Join Date: Jun 2007
Posts: 3,214
Received Thanks: 758
Bedanke mich schonmal, kenne zwar alles schon, aber ist schön erklärt.

Liebe Grüße,
pand0r
Pand0r is offline  
Old 03/07/2010, 09:24   #5
 
elite*gold: 320
Join Date: Mar 2010
Posts: 40
Received Thanks: 9
Quote:
Originally Posted by Pand0r View Post
Bedanke mich schonmal, kenne zwar alles schon, aber ist schön erklärt.

Liebe Grüße,
pand0r
Falls es wer braucht,habs da auf der Seite gesucht und davon hier nix gab wollt ichs public machen
A7!9 is offline  
Reply


Similar Threads Similar Threads
Sichere Yang seite?
06/27/2010 - Metin2 - 16 Replies
Hey e*PVp^^ Hab so ne Yang seite gefunden.. undzwar die hier: Money-Gaming Aber ich trau mich i.wie nicht da einzukaufen ^^ Der Support ist zwar so super nett, und die helfen auch einen.. aber bin trozdem stuzig.. kennt ihr da vielleicht etwas?
[C++]Schleifen,Statements,Menü?
06/11/2010 - C/C++ - 7 Replies
Hi ich hab in etwa das gleiche Problem wie VersionX im Main Bereich :) Ich bin auch anfänger kann aber schon einiges :cool: :P xD Hier mal ein Code(damit ihr es euch vorstellen könnt): #include <iostream> #include <string> using namespace std;
hackers out there! u can post ur statements here ^^
05/13/2009 - Grand Chase - 32 Replies
juz read the rules over and over again (5x actually) im hopin that this thread will somehow enlightened those MISUSERS on how to use their hacks or someone else's properly. and i guess that this post will not break any of this forum's rules so.. here we go! Why or what is/are the reason/s why you are using hacks in the game? ;) ME= use this hacks coz i want to catch up to my friends playin for a whole weekend w/c are lvl 50+. ( i do have a job ) i guess this hacks really makes me...
Welcher sichere Levelservice?
09/17/2007 - World of Warcraft - 10 Replies
Hoi! Will mir auf einem 2 Account ein Hexenmeister hochspielen lassen. Da ich bereits auf meinem Main Account schon eine verwarnung habe und ein andere Account perm. gebannt wurde bin ich am überlegen ob es überhaupt noch was bringt? Gibt es eventuell ein Levelservice der garantiert nicht gebannt zu werden oder bei bannung ersetzt wird? Würde auch deswegen mehr zahlen ....mir fehlt halt einfach die Zeit um selber zu spielen....:(. Meine Meinung nach Verwarnen die GMs sowieso nur weil der...



All times are GMT +1. The time now is 22:11.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.