[PHP] Richtig Escapen?

DadyCool

Well-known member
ID: 81813
L
30 April 2006
601
19
Hi,

ich kenne mich mit PHP-Sicherheit leider nicht so aus. Habe gelesen, dass man die Daten aber immer erst Escapen soll bevor diese in der DB geschrieben werden.

Meine Funktion:
PHP:
$str = trim($str); // Leerzeichen am ende und anfang weg machen
$str = preg_replace('/\S{60}/', '\0 ', $str);   // Nach 60 Zeichen kommt ein umbruch
$str = htmlentities($str); // HTML umwandeln
$str = addslashes($str); // Zeichen maskieren
$str = nl2br($str); // umbruch zu <br /> machen

dann stehen die Daten maskiert in der DB. Wie sollte ich die denn aber wieder auslesen?

DadyCool
 
habe mich etwas ungeschickt ausgedrückt...

Ich habe einfach nen Denkfehler....

Also erst maskiere ich die Zeichen, damit diese sicher in der DB stehen und anschließend wandle ich sie wieder zurück damit diese richtig auf der HP angezeigt werden.

Aber ist das nicht das gleiche, als würde ich sie überhaupt nicht maskieren?

DadyCool
 
Ich vermute mal, dass der Autor des Artikels/Buches, das du gelesen hast, damit einen Schutz vor SQL-Injection erreichen möchte.

ja darum geht es...


Also bei einem INTO maskiere ich die Daten. Bei einem Select entferne ich dann die Maskierung, damit die Zeichen auf der PHP Seite richtig angezeigt werden.
Habe ich damit nicht die Sicherheit wieder aufgehoben...? bin ein wenig verwirt....:oops:


DadyCool
 
Das Problem ist, dass du, wenn du SQL Abfragen machst, ganz einfach auch "andere" Abfragen einfügen kannst. So kann man bei einem einfachen Login-System folgendes als Usernamen nehmen: admin , und als Passwort '.TRUE.' - Damit käme man mit jedem Passwort rein. Nun, mysql_real_escape_string schützt dich vor solchen Injektionen. Es macht allen ' ein \ vorne drann. Das blöde ist aber dann meistens, dass Volltext mit " drinnen auch \-e bekommt, so dass man sie bei der Auslese und dem Anzeigen davor noch stripslashes verwenden muss.
 
Keine Sorge. Das ist soweit korrekt. Du solltest dich ein wenig einlesen was SQL-Injection angeht, um zu verstehen wie das funktioniert und was du mit dieser Methode machst, um es zu verhindern.
 
um sql injections zu verhindern nimmt man addslashes oder noch besser eine dazu eventuell vorhande funktion. wie zb bei mysql mysql_real_escape_string... damit ist man vor sql injections sicher bzw. sicherer. mit den befehl wird der string aber nur maskiert und diese maskierung hebt sich automatisch wieder auf. sprich wenn du jetzt "hallo 'du' da" speichern willst wird der string erst maskiert "hallo \'du\' da" und diese maskierung wird beim speichern wieder entfernt. also steht dann "hallo 'du' da" in der datenbank... somit kannst du die daten ohne umstände auslesen.

das andere was du gepostet hast eigent sich nicht um vor sql injections zu schützen...
  • trim($str) = kein schutz... entfernt nur überflüssige withspaces (leerzeichen,tabs,zeilenumbrüche) am ende und am anfang vom string (was aber mysql zb bei varchar automatisch mach)
  • preg_replace('/\S{60}/', '\0 ', $str) = splittet zu lange strings... damit wird verhindert das das design explodiert wenn jemand zb sowas schreibt "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" (das forum hat sowas auch eingebaut)
  • htmlentities($str) = schützt vor html code... also auch vor cros site scripting.
  • nl2br($str) = für die ausgabe von text feldern in formularen wichtig... ersetzt die zeilenumbrüche gegen <br />. somit bleibt die absatz formatierung erhalten wenn man die eingabe einer <textarea> auf einer html seite darstellt.
das ganze ist eigentlich alles nötig um user eingaben auf einer website darzustellen. ansonsten könnte man am ende probleme bekommen...

die frage wo man das alles anwendet ist ne andere sache... es kann vorteile und nachteile haben die daten schon von vornherein so umgewandelt in der datenbank gespeicher zu haben oder erst bei der ausgabe umzuwandeln.
 
Zuletzt bearbeitet:
um sql injections zu verhindern nimmt man addslashes oder noch eine dazu eventuell vorhande funktion. wie zb bei mysql mysql_real_escape_string... damit ist man vor sql injections sicher bzw. sicherer. mit den befehl wird der string aber nur maskiert und diese maskierung hebt sich automatisch wieder auf. sprich wenn du jetzt "hallo 'du' da" speichern willst wird der string erst maskiert "hallo \'du\' da" und diese maskierung wird beim speichern wieder entfernt. also steht dann "hallo 'du' da" in der datenbank... somit kannst du die daten ohne umstände auslesen.

das andere was du gepostet hast eigent sich nicht um vor sql injections zu schützen...
trim($str) = kein schutz... entfernt nur überflüssige withspaces (leerzeichen,tabs,zeilenumbrüche) am ende und am anfang vom string (was aber mysql zb bei varchar automatisch mach)
preg_replace('/\S{60}/', '\0 ', $str) = splittet zu lange strings... damit wird verhindert das das design explodiert wenn jemand zb sowas schreibt "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" (das forum hat sowas auch eingebaut)
htmlentities($str) = schützt vor html code... also auch vor cros site scripting.
nl2br($str) = für die ausgabe von text feldern in formularen wichtig... ersetzt die zeilenumbrüche gegen <br />. somit bleibt die absatz formatierung erhalten wenn man die eingabe einer <textarea> auf einer html seite darstellt.

das ganze ist eigentlich alles nötig um user eingaben auf einer website darzustellen. ansonsten könnte man am ende probleme bekommen...

die frage wo man das alles anwendet ist ne andere sache... es kann vorteile und nachteile haben die daten schon von vornherein so umgewandelt in der datenbank gespeicher zu haben oder erst bei der ausgabe umzuwandeln.

danke, für deine Erklärung, wenn ich das richtig verstanden habe bedeutet das: Dass das INTO nicht manipuliert werden kann. In der DB steht aber alles unmaskiert drin. Wenn ich jetzt ein Select mache muss ich das dann wieder maskieren, damit evtl Code nicht ausgeführt werden kann, oder?



DadyCool
 
Zuletzt bearbeitet:
Du maskierst Sachen (\', HTML, <br>), du schickst die maskiert in die DB. Beim Auslesen musst du meines Wissens her blos die Back-Slashes (\) entfernen (mit stripslashes).
 
also, schau mal in den Snippets-Bereich hier im Programmierforum, ich habe dort einen kleinen Code gepostet, der dich komplett vor mysql-injections schützt und dabei musst dur dir keine gedanken machen, zudem werden deine querys ordentlich formatiert
 
Du meinst mit Sicherheit die hier:
https://www.klamm.de/forum/showpost.php?p=523839&postcount=7

;-)

Dazu mal ein paar Fragen:
Du schreibst die Query soll so aufgerufen werden:
db_query('SELECT * FROM %s WHERE `%s`=%d','user','klammid',93995);

um die jetzt in einem vorhandenem Script einsetzen zu können müste jede Query umgearbeitet werden. Bei den meisten Scripten sieht es ja etwa so aus:
mysql_query('SELECT * FROM user WHERE `klammid`= $_POST['klammid']');

Wenn ich da einfach aus mysql_query ein db_query mache, würde deine Funktion das dann auch noch vor mysql-injections schützen?

Wo find ich Infos über diese %s, %d?

Grüße
Marc
 
nein, wenn du einfach den Namen änderst gibt es keinen Schutz, wie auch.
ich würde aufjedenfall raten dann die ganzen stellen im script zu ändern, weil:
1.) es ist sicher
2.) diese schreibweise ist viel leichter zu lesen, als wenn du dauernd aus dem string rein und raus shiftest weil du variablen einfügen möchtest

btw: würde dein mysql-aufruf in dem beispiel auch noch einen parse-error generieren
 
Könntest du mir bitte erklären warum nicht?
Das Eintragen der Werte in die DB klappt klappt auch wenn ich nur den Namen änder.
Also was macht das Formatieren der Strings sicherer als unformartierte Strings?

hättest du dich mit meinem kleinen Snippet beschäftigt, hättest das verstanden :roll:
Bei meiner Funktion werden alle Parameter (ab dem 2.) gegen MySQL-Injections geschützt, der Grundquery nicht, natürlich nur die Parameter.