# Thema Sicherheit: mysql_real_escape_string() & magic_quotes_gpc



## Don Stefano (18. Juli 2005)

Hallo zusammen,

 da ich eh gerade meine Datenbankkommunikation umprogrammiere (der Probleme halber weg von der Objektorientierung) würde ich sie auch gern sicher machen und vor SQL Injektionen schützen.

           Dies geschieht ja mit der Funktion mysql_real_escape_string() z.B. folgendermaßen:


```
$query = " 
         		UPDATE `tabelle` 
    		 SET `name`	 = '".mysql_real_escape_string($name)."',
        `geschlecht`	 = '".mysql_real_escape_string($geschlecht)."', ...
```
          anstatt 


```
$query = ("update tabelle SET name='$name', geschlecht=$geschlecht",...
```
 Meine Frage dazu. Ist dies für sämtliche Variablen notwendig, mit denen in den Skripten gearbetet wird, und die irgendwie mit der Datenbank in Verbindung stehen ?

        Und dann habe ich unter dem angegebenen Link gelesen: "Falls      Sie magic_quotes_gpc      aktiviert haben und mit Daten aus Benutzereingaben arbeiten, müssen Sie      vorher Ihre Daten mit stripslashes() behandeln."

        Auf meinem Webserver ist magic_Quotes_gpc aktiviert und zwar nur dieses magic_quotes.

        So wie ich das verstehe muss ich also stripslashes() bei jeder Variable verwenden, sie ich mit mysql_real_escape_string() "maskiere". Ist das wirklich notwendig?

        Wie sähe dann der angepasste Code aus, den ich oben abgebildet habe? Folgendermaßen ?


```
$query = " 
          		UPDATE `tabelle` 
 		 SET `name`	 = '".mysql_real_escape_string(stripslashes($name))."',
         `geschlecht`	 = '".mysql_real_escape_string(stripslashes($geschlecht))."', ...
```
 
      Ist das so korrekt?
      Was gibts es zu dem Thema noch zu wissen ? Oder bin ich dann damit vor SQL Injektionen sicher?

 Außerdem würde mich mal folgendes interessieren. Ich habe eine Datei mit meinen Datanbankdaten, die zum DB-Aufbau immer includet wird. Ist es nicht unsicher, wenn die einfach so auf dem Server liegt, und kann man die Daten, die sie enthält nicht auch irgendwie den "laufenden Skripten" entnehmen (in böser Absicht)?


      Danke für Eure Ratschläge und Hinweise


----------



## mrepox (19. Juli 2005)

...Verwenden Sie daher die Funktion addslashes() nicht, wenn Strings bereits durch magic_quotes_gpc escaped wurden, ansonsten erhalten Sie doppeltes Escaping. Um herauszufinden, ob der Parameter aktiviert ist, verwenden Sie am Einfachsten die Funktion get_magic_quotes_gpc(). 

http://www.php-homepage.de/manual/function.addslashes.php




Zu deinem DB Script ist zu sagen,das es nur vom Server aus arbeitet. Dieses Script ist ja nur für deine Connection zur Db zuständig und gibt die Daten nicht an den Client zurück.

Sicher ist jedoch nichts..


----------



## Gumbo (19. Juli 2005)

Allgemein sollten _alle_ Parameter, auf die ein Außenstehender direkt oder indirekt Einfluss nehmen kann, validiert werden. Bei numerischen Parameterwerten wäre die Umwandlung der Parameterwerte in einen numerischen Typ angemessen (s. Typen-Umwandlung). Bei Zeichenketten wäre die Nutzung der mysql_real_escape_string()-Funktion eine gute Maßnahme sich vor gefährlichen Werten zu schützen.

Was die „magic_quotes“-Geschichte angeht, ist es möglich diese Einstellung entweder für die Laufzeit des Skriptes oder allgemein abzuschalten. Damit wäre auch die Frage nach der zusätzlichen Nutzung der stripslashes()-Funktion erledigt.

Zu deiner letzen Frage kann ich nur sagen, dass solange die Daten ordentlich als PHP-Konstanten oder -Variablen definiert sind, vor fremdem Zugriff geschützt sind. Auch sollte es nicht möglich sein, den Quellcode eines PHP-Skriptes über die Erweiterung phps einzusehen.


----------



## hpvw (19. Juli 2005)

Ich würde folgende Syntax verwenden, falls Du mit dem Skript auch mal umziehst oder Dein Hoster die Eintellungen ändert:
	
	
	



```
"... ".
    mysql_real_escape_string(
        ((get_magic_quotes_gpc()==1)
            ?stripslashes($name):$name)).
    " ..."
```
Damit entfernst Du die durch magic_quotes automatisch hinzugefügten Backslashes auch nur, wenn diese tatsächlich hinzugefügt wurden, theoretisch zumindest. Testen solltest Du das noch mal.
Wenn register_globals off ist, dann musst Du nur die Daten mit mysql_real_escape_string bearbeiten, die direkt oder indirekt (also Bestandteile einer Usereingabe enthalten) von einem Formular kommen. Dazu mußt Du bei im Skript definierten Variablen natürlich darauf achten, dass Du Dich nicht selbst "injectest".

Gegen Deinen letzten Absatz helfen u.a. folgende Maßnahmen:
Den Ordner mit der Konfiguration mit .htaccess schützen. So hat der User keinen direkt Zugriff auf die Datei.
"Sauber" programmieren und darauf achten, dass die definierten Variablen nur im gewünschten Kontext verwendet werden (z.B. nicht mit $$ oder eval arbeiten).
Du bist nun von der objektorientierung weg, jedoch lassen sich diese Daten in PHP5 auch in einer Datenbankklasse als private deklarieren und sind damit außerhalb der Klasse nicht sichtbar. Dann mußt Du "nur" noch darauf achten, dass die Daten nicht in irgendeinem Rückgabewert oder einer Ausgabe verwendet werden können.
Damit der .htaccess-Schutz nicht umgangen wird, musst Du darauf achten, dass nicht durch ein Skript ungeprüft Dateien eingebunden oder durchgeschleust werden, wie es z.B. häufig bei Bildergallerien mit den Bildern gemacht wird.

Gruß hpvw


----------



## Gumbo (19. Juli 2005)

Sonst könntest du dir auch eine Konstrukt zum Entfernen der Maskierungszeichen zusammenbastelt:
	
	
	



```
<?php

	function stripslashes_deep($value) {
		return is_array($value)
			? array_map('stripslashes_deep', $value)
			: stripslashes($value);
	}

	if( get_magic_quotes_gpc()===1 ) {
		$_GET    = array_map('stripslashes_deep', $_GET);
		$_POST   = array_map('stripslashes_deep', $_POST);
		$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
	}

	…

?>
```
Noch etwas zu deiner letzen Frage: Du könntest auch mit folgendem Konstrukt prüfen, ob ein Skript nicht direkt aufgerufen wurde. Nur wenn es von einem weiteren Skript eingebunden wurde, bricht es nicht ab:
	
	
	



```
<?php

	if( realpath($_SERVER['SCRIPT_FILENAME']) === realpath(__FILE__) ) {
		header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
		exit;
	}

	…

?>
```


----------



## hpvw (19. Juli 2005)

Um nicht unnötige Informationen zu liefern würde ich 404 statt 403 senden, auch, wenn es gelogen ist.


----------



## Gumbo (19. Juli 2005)

Du hast recht, hqvw, der Status-Code 404 ist hier wirklich passender. Ich habe meinen vorherigen Beitrag entsprechend angepasst.


----------



## Don Stefano (19. Juli 2005)

Erst einmal Dankeschön für die Beiträge. Daraus resultieren für mich nun folgende Verständnisfragen:

*  1) *Bezugnehmend auf die Datei, die meine Datenbankdaten enthält schrieb Gumbo die Daten sollten *"ordentlich" als PHP-Konstanten oder -Variablen definiert* sein und es sollte nicht möglich sein, den Quellcode eines PHP-Skriptes über die Erweiterung phps einzusehen.

        Hier mal der kurze Code:


```
<?php
        //Paramter fuer die Datenbankverbindung
        $server = "localhost";
        $user = "root";
        $passwd = "";
        $datenbank = "votum";
        
        // Versuchen, die DB-Verbindung herzustellen
        $verbindung = mysql_connect ($server, $user, $passwd);
 if(!$verbindung) die("Datenbankverbindung konnte nicht hergestellt werden. Fehler " . mysql_errno() .": ". mysql_error());
        
        //Auswahl der entsprechenden Datenbank
 if (!mysql_select_db ($datenbank)) die("Datenbankverbindung konnte nicht hergestellt werden. Fehler " . mysql_errno() .": ". mysql_error());
        ?>
```
 .
 Diese Datei wird alse includet bzw. required in den Skripten, die mit der Datenbank arbeiten. DIe Querys sind dann in diesen Skripten.

 Wie aber muss ich die Variablen nun in Gumbos Sinne "sicher" definieren? Und wie verhindere ich die Einsicht über phps (und was ist das überhaupt?


*  2) Numerische Werte vs. Zeichenketten*

 Bei numerischen Parametern empfiehlt Gumbo die Umwandlung in einen entsprechenden Variablentypen. Würde es dazu ausreichen nach der Eingabe durch den Nutzer numerische Variablen folgendermaßen in der Query zu spezifizieren?


```
$result = mysql_query("select * from tabelle where besitzerid='(int) $besitzerid'");
      $result = mysql_query("insert into tabelle (besitzerid) values('(int) $besitzerid')");
```
      Oder muss das an anderer Stelle mit settype() geschehen?

 Resumierend sollte ich alse numerische Parameter wie hier beschrieben behandeln und Zeichenketten (z.B. Name oder Passwort) mit mysql_real_escape_string().

      Ist das alles unter Punkt 2 soweit richtig?

*
    3) magic_quotes_gpc()*

 Ich habe gelesen man könnte das auch für die Verwendung meiner Skripte deaktivieren? Wie geht das ? Auf die php.ini meines Servers habe ich leider keinen Zugriff und dort ist magic_quotes_gpc() aktiviert.

 Aller weiteren Fragen (2 hätte ich sonst noch) hätten sich damit erledigt, wenn man die magic_quotes_gpc() für meine Skripte abschalten kann.

    Vielleicht wärst Du so nett (Gumbo),  DIch nochmals dazu zu äußern.

    Tante Grazie


----------



## Gumbo (19. Juli 2005)

> Vielleicht wärst Du so nett (Gumbo), DIch nochmals dazu zu äußern.


Gerne.

Zu deiner erstem Punkt: Solange das Skript wirklich nur als PHP-Quellcode vom Webserver behandelt wird, dürfte es nicht möglich sein den Inhalt der Variablen einzusehen. Du könntest die Daten zur Datenbankverbindung aber auch gleich direkt als Parameter der mysql_connect()-Funktion übergeben, ohne erst noch Variablen zu definieren. Desweiteren könntest du noch den zweiten Beispielcode aus meinem vorherigen Beitrag an den Anfang des Skriptes setzen um noch einmal mehr auf Nummer Sicher zu gehen.

Zu deinem zweiten Punkt: Hier einmal eine Beispiel-Abfrage:
	
	
	



```
<?php

	$query = "
		INSERT INTO
		        `Tabelle`
		  SET
		        `Spalte-1` = ".intval($_POST['numerischer-Parameter']).",
		        `Spalte-2` = '".md5(trim($_POST['Passwort-oder-ähnlich-zu-behandelnder-Parameter']))."',
		        `Spalte-3` = '".mysql_real_escape_string($_POST['beliebige-Zeichenketten-Parameter'])."'
		";
	mysql_query($query) or die('<p><strong>Fehler bei der Datenbankabfrage:</strong> '.htmlspecialchars(mysql_error()).'</p><pre>'.htmlspecialchars($query).'</pre>');
	…

?>
```
Es ist auch meistens hilfreich direkt bei einer fehlgeschlagenen Datenbankabfrage die Abfrage selbst auszugeben – zumindest während der Entwicklung.

Zu deinem dritten Punkt: Mit der ini_set()-Funktion ist es möglich die Konfigurationseinstellungen für die Laufzeit des Skriptes zu ändern. Möchtest du eine Einstellung langfristiger ändern, ist dies möglicherweise mit der Apache-Direktive php_value möglich.
Sonst müsstest oder könntest du eben auf den ebenfalls in meinem vorherigen Beitrag beschrieben Algorithmus zum Entfernen der automatisch gesetzten Maskierungszeichen zurückgreifen. Damit sollte es dann auch funktionieren.


----------



## Don Stefano (20. Juli 2005)

Danke, ich muss das morgen einmal alles an einem Beispiel durchprobieren um zu sehen, ob ich alles verstanden habe.

  Ich poste das Ergebnis dann mal hierhin und stelle ggf. noch die ein oder andere Frage.


----------



## ManicMarble (20. Juli 2005)

Zwischenfrage:
Was ist eigentlich der Unterschied zwischen mysql_real_escape_string() und addslashes(), außer dass die eine Funktion an den MySQL-Server weitergereicht wird während die andere vom PHP-Parser bearbeitet wird? Eigentlich machen die beiden doch das selbe, oder?
Ich könnte mir vorstellen, dass mysql_real_escape_string() einfach "MySQL-spezifischer", also entsprechend der verwendeten MySQL-Version escaped und damit geeigneter weil zukunftssicherer ist...

Ich habe jedenfalls in allen meinen älteren Scripten Formular-Angaben immer nur mit addslashes() escaped. Muss ich die alle umarbeiten? Oh, bitte nicht...  

_Martin_


----------



## Gumbo (20. Juli 2005)

Laut der Syntax einer Zeichenkettendeklaration in MySQL müssen die ASCII-Zeichen mit der hexadezimalen Darstellung (s. ASCII-Zeichentabelle) 0x00, 0x08, 0x09, 0x0A, 0x0D, 0x1A, 0x22, 0x27 und 0x5C _immer_ durch ein vorangestelltes \-Zeichen maskiert werden. (Die Maskierung der Anfühunrgszeichen 0x22 und 0x27 ist nur je nach eingrenzende Anführungszeichen erforderlich)

Wo die mysql_real_escape_string()-Funktion alle Zeichen bis auf das Backspace-Zeichen (0x08) maskiert, beachtet die addslashes()-Funktion nur die Zeichen 0x00, 0x22, 0x27 und 0x5C.


----------



## ManicMarble (20. Juli 2005)

Aha, 1000 Dank.

Also mysql_real_escape_string() maskiert zusätzlich Backspace, Tab, Linefeed, Carriage Return, und SUB.
Diese Zeichen sind doch eigentlich nicht unbedingt kritisch bei Strings die über HTML-Formulare "reinkommen" bzw. lassen sich nicht in Textfelder eingeben, oder? Die CRs und LFs die in Textareas eingegeben werden, wurden auch bisher immer korrekt gespeichert.

Kann ich also meine alten Scripte so lassen? Oder muss ich trotzdem alle Scripte umschreiben um vor Injections sicher zu sein? Was meint ihr?


----------



## Gumbo (20. Juli 2005)

Ich konnte sämtliche Steuerzeichen übermitteln. Dennoch kann ich durch nachfolgenden Test behaupten, dass der praktische Einsatz der addslashes()-Funktion gegenüber der mysql_real_escape_string()-Funktion zumindest auf meinem lokalen System unbedenklich ist. Denn entfernt man den dritten Ausdruck mit dem Alias „c“ gibt es keine Fehlermeldung.
	
	
	



```
<?php

	mysql_connect([…]);
	$string = '';
	for( $i=0; $i<=128; $i++ ) {
		$string .= chr($i);
	}

	$query = "
		SELECT
		        '".mysql_real_escape_string($string)."' AS `a`,
		        '".addslashes($string)."' AS `b`,
		        '".$string."' AS `c`
		";
	$result = mysql_query($query) or die('<p><strong>Fehler bei der Datenbankabfrage:</strong> '.htmlspecialchars(mysql_error()).'</p><pre>'.htmlspecialchars($query).'</pre>');
	var_export(mysql_fetch_array($result, MYSQL_ASSOC));

?>
```
Dies kann natürlich von System zu System wieder unterschiedlich sein, möglicherweise greift PHP auch noch vor dem Versenden der Anfrage sellbst ein.

Generell würde ich jedoch den Gebrauch der mysql_real_escape_string()-Funktion der addslashes()-Funktion vorziehen. Denn die Funktion wurde ja nicht ganz ohne Bedacht definiert.


----------



## ManicMarble (20. Juli 2005)

Gumbo hat gesagt.:
			
		

> Ich konnte sämtliche Steuerzeichen übermitteln. ...


Wie übermittelst Du denn beispielsweise einen Backspace über ein HTML-Textfeld? Ok, man könnte den Value des Textfeldes per JS setzen, aber sonst... na egal.

Wichtiger ist, dass mich Deine Aussage beruhigt und in meiner Meinung bestätigt. SQL-Injections bauen ja hauptsächlich darauf, dass "Quotes" nicht maskiert werden, um ein bösartiges SQL-Statement dranzuhängen. Und da auch addslashes() alle Quotes brav maskiert...



			
				Gumbo hat gesagt.:
			
		

> Generell würde ich jedoch den Gebrauch der mysql_real_escape_string()-Funktion der addslashes()-Funktion vorziehen. Denn die Funktion wurde ja nicht ganz ohne Bedacht definiert.


Klar, mache ich ja auch seit einiger Zeit so.

Nochmal Danke,
_Martin_


----------



## Don Stefano (22. Juli 2005)

So, endlich finde ich die Zeit mich weiter um die Sicherheit meiner Skripte zu kümmern.

 Als erstes würde ich noch einmal kurz auf die Sicherheit meines Skriptes, mit den Datenbankdaten eingehen. Ich habe zuerst einmal mit .htaccess das Verzeichnis, in welchem diese Datei auf dem Server liegt, vor Zugriffen geschützt.

 Dann habe ich Gumbos Code mit dort eingefügt. Ich gehe davon aus, dass es richtig es daran nichts zu verändern? Nun sieht das Skript im Vergleich zu oben wie folgt aus und es funktioniert auch auf dem Server.:


```
<?php
              
              //Zuerst die Abfrage, ob das Skript aus einem anderen aufgerufen wird
              if( realpath($_SERVER['SCRIPT_FILENAME']) === realpath(__FILE__) ) { 
             		header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found'); 
             		exit; 
             	} 
              
             		//Paramter fuer die Datenbankverbindung
             		$server = "localhost";
             		$user = "root";
             		$passwd = "";
             		$datenbank = "votum";
             		
             		// Versuchen, die DB-Verbindung herzustellen
             		$verbindung = mysql_connect ($server, $user, $passwd);
       if(!$verbindung) die("Datenbankverbindung konnte nicht hergestellt werden. Fehler " . mysql_errno() .": ". mysql_error());
             		
             		//Auswahl der entsprechenden Datenbank
 if (!mysql_select_db ($datenbank)) die("Datenbankverbindung konnte nicht hergestellt werden. Fehler " . mysql_errno() .": ". mysql_error());
             		?>
```
 *Dazu habe ich also KEINE Fragen mehr, es sei denn ich hätte irgendwas falsch gemacht? Vielen Dank schon einmal dafür!*


 Dann ein schönes Beispiel für die Maskierung von Formulareingaben beim Speichern in die Datenbank (SQL-Injektion-Schutz) - und zwar mein Feedbackformular mit dem User einige Angaben machen können, wie Ihnen das Angebot gefällt. Sie enthält sowohl Text (Strings) als auch Zahlenwerte, die aus einem Drop-Down Menu stammen.

            Zuerst werden die mittels POST übertragenen Variablen eingelesen:


```
//Variabeln einlesen aus dem Formular
            $beurteilung = trim(@$_POST["beurteilung"]);
            $verbesserung = trim(@$_POST["verbesserung"]);
            $anmerkung = trim(@$_POST["anmerkung"]);
            $wieder = trim(@$_POST["wieder"]);
            $empfehlen = trim(@$_POST["empfehlen"]);
            
            //Variable aus der Session verfuegbar machen
            $besitzerid = $_SESSION["besitzerid"];
```
          Bislang wurden diese Variablen dann einfach ungeprüft in die Datenbank geschrieben, nämlich:

```
<?php
        
        //Diese Daten werden jetzt in die Datenbanktabelle kontakt geschrieben
          	 
 	 $result = mysql_query("insert into kontakt (besitzerid, beurteilung, verbesserung, anmerkung, wieder, empfehlen) values('$besitzerid', '$beurteilung', '$verbesserung', '$anmerkung', '$wieder', '$empfehlen')");
 	if(!$result) die("Die Kontaktformulardaten konnten nicht gespeichert werden. Fehler " . mysql_errno() .": ". mysql_error());
        	 ?>
```
 
       Und nun habe ich es folgendermaßen geändert. Dabei ist noch wichtig zu erwähnen, dass ich die magic_quotes abgeschaltet habe!


```
<?php
      
 $result = mysql_query("INSERT INTO kontakt (besitzerid, beurteilung, verbesserung, anmerkung, wieder, empfehlen) values('".mysql_real_escape_string($besitzerid)."', ".intval($beurteilung).", '".mysql_real_escape_string($verbesserung)."', '".mysql_real_escape_string($anmerkung)."', '".mysql_real_escape_string($wieder)."', '".mysql_real_escape_string($empfehlen)."')"); 
   
       	?>
```
 
 Aber irgendwas scheint da nicht zu funktionieren. Denn in meiner Datanbank landen die Daten in genau der selben Form wie mit ohne den Maskierungsfunktionen. Außerdem habe ich die Variable $beurteilung mal als string eingegeben und der Wert wird trotz ".intval($beurteilung).", auch als String in der Datenbank gespeichert. 

  Ist das richtig so ? Oder muss ich wirklich INSERT INTO SET verwenden und es geht nicht mit INSERT INTO VALUES ?

 Fehlermeldungen habe ich jedenfalls keine bekommen. Ich hoffe Gumbo oder jemand anderes erbarmt sich erneut und hilft mir auf die Sprünge.


----------



## Gumbo (22. Juli 2005)

Zu deinem ersten Skript möchte ich sagen, dass eine Variablen-Definition für einmalig genutze Werte völlig überflüssig ist. Dementsprechend kannst du die Datenbankverbindungsdaten direkt als Zeichenkette als Parameter übergeben: mysql_connect('localhost', 'root', ''). Übrigens entsprechen die Default-Parameterwerte dieser Funktion genau deinen Datenbankverbindungsdaten, sodass du die Parameter auch gleich weglassen könntest: mysql_connect().

Zu deinem zweiten Skript: Ich hätte die Daten wahrscheinlich so oder ähnlich verarbeitet:
	
	
	



```
<?php

	…

	$_POST['beurteilung'] = ( isset($_POST['beurteilung']) && intval($_POST['beurteilung'])>0 )
		? intval($_POST['beurteilung'])
		: null;
	$_POST['verbesserungen'] = ( isset($_POST['verbesserungen']) && trim($_POST['verbesserungen'])!=='' )
		? trim($_POST['verbesserungen'])
		: null;
	$_POST['anmerkung'] = ( isset($_POST['anmerkung']) && trim($_POST['anmerkung'])!=='' )
		? trim($_POST['anmerkung'])
		: null;
	$_POST['wieder'] = ( isset($_POST['wieder']) && trim($_POST['wieder'])!=='' )
		? trim($_POST['wieder'])
		: null;
	$_POST['empfehlen'] = ( isset($_POST['empfehlen']) && trim($_POST['empfehlen'])!=='' )
		? trim($_POST['empfehlen'])
		: null;

	// mögliche Bedingung gegen Fehleingaben
	// if( !is_null($_POST['beurteilung']) && !is_null($_POST['verbesserung']) && !is_null($_POST['anmerkung']) && !is_null($_POST['wieder']) && !is_null($_POST['empfehlen']) ) {

	$query = "
		INSERT INTO
		        `kontakt`
		  SET
		        `besitzerid`   = '".$_SESSION['besitzerid']."',
		        `beurteilung`  = ".$_POST['beurteilung'].",
		        `verbesserung` = '".mysql_real_escape_string($_POST['verbesserung'])."',
		        `anmerkung`    = '".mysql_real_escape_string($_POST['anmerkung'])."',
		        `wieder`       = '".mysql_real_escape_string($_POST['wieder'])."',
		        `empfehlen`    = '".mysql_real_escape_string($_POST['empfehlen'])."'
		";
	$result = mysql_query($query)
		or die('<p><strong>Fehler bei der Datenbankabfrage:</strong> '.htmlspecialchars(mysql_error()).'</p><pre>'.htmlspecialchars($query).'</pre>');

	// }

	…

?>
```
Ich persönlich bevorzuge die SELECT-Syntax mit SET-Klausel, die ist mir einfach übersichtlicher. Dennsoch sollte auch die andere Syntax funktionieren.


----------



## Don Stefano (22. Juli 2005)

Vielen lieben Dank für die neuen Tips und Hilfen.

   Jetzt würde mich nur noch interessieren, wie ich denn überprüfen kann, ob das wirklich funktioniert. 

   Was müßte ich also in der Eingabe des Formulars als Text z.B. angeben und was sollte dann nach .mysql_real_escape_string  in der Datenbank stehen ?

   Oder steht in der Datenbank immer das Gleiche und ich kann mir das Ergebnis dieser Funktionen gar nicht anschauen?

  Über ein Beispiel würde ich mich freuen.


----------



## hpvw (22. Juli 2005)

Du maskierst die Zeichen, damit das Zeichen selbst in die Datenbank eingetragen wird.
Einen Unterschied merkst Du nur, wenn das Query mit unmaskierten Einträgen einen Fehler verursacht.
http://dev.mysql.com/doc/mysql/de/string-syntax.html

Gruß hpvw


----------



## Don Stefano (22. Juli 2005)

Ok, wenn ich das nun richtig verstanden habe so kann ich davon ausgehen, dass ich es richtig gemacht habe, solange keine Fehlermeldungen erscheinen beim Versuch die Daten in die Datenbank zu transferieren.

 Grazie
 Euer Don


----------



## Don Stefano (23. Juli 2005)

Das scheint soweit wo nun alles dementsprechend aktualisiert ist ohne Fehler zu funktionieren.

    Nur bei einer einzigen Sache bin ich noch unsicher. Und zwar dort wo ich für den Mitgliederbereich das Passwort verschlüssel.


        Das geschah bislang folgendermaßen:

```
$result = mysql_query("insert into tabelle (login,passwort,email) values('$login',PASSWORD('$passwd'),'$email')");
```
        und abgefragt wurde es dann beim einloggen in einem anderen Skript mit:

```
$result = mysql_query("SELECT besitzerid FROM tabelle WHERE login='$login' and passwort=PASSWORD('$passwd')");
```
 

       In welcher Syntax muss das aber nun mit md5 und Maskierung geschehen? Ich dachte folgendermaßen:


```
$result = mysql_query("insert into tabelle (login,passwort,email) values ('".mysql_real_escape_string($login)."',md5('".mysql_real_escape_string($passwd)."'),
   '".mysql_real_escape_string($email)."')");
```
       und

```
$result = mysql_query("SELECT besitzerid FROM tabelle WHERE login='".mysql_real_escape_string($login)."' and passwort=md5('".mysql_real_escape_string($passwd)."')");
```
 
       Meine hoffentlich letzte Frage zu diesem Thema: Kann ich das Ganze nun somit als balbwegs injektionssicher betrachten und ist die Verschlüsselung mit md5 (weil hexadezimal) besser als die mit PASSWORD ?


----------



## Gumbo (23. Juli 2005)

Auch PHP besitzt die md5()-Funktion. Damit könntest du den Hash-Wert berechnen ohne noch zusätzlich eine maskierende Funktion wie mysql_real_escape_string() einsetzen zu müssen:
	
	
	



```
<?php

	…
	$query = "
		SELECT
		        `besitzerid`
		  FROM
		        `tabelle`
		  WHERE
		        `login`    = '".mysql_real_escape_string($login)."'
		    AND `passwort` = '".md5($passwd)."'
		";
	$result = mysql_query($query);
	…

?>
```
Das ist auch einer der Vorteile gegenüber MySQLs PASSWORD()-Funktion: sie ist einfach in fast jeder Programmier- bzw. Skriptsprache sowohl server- als auch clientseitig verfügbar.


----------



## Don Stefano (24. Juli 2005)

Vielen Dank für die Aufklärung. Da es scheinbar auch so funktioniert, wie ich es nun gemacht habe, lasse ich es aber erst einmal so. Es sei denn es spricht irgendetwas dagegen.


----------

