PHP: POST- und GET-Eingaben escapen, unerwünschte Zeichen löschen

sabermaul

Semiprofi
Thread Starter
Mitglied seit
06.05.2007
Beiträge
3.741
Hi!

Ich versuche schon seit Mitte Juli mir eine Funktion zu schreiben, die die POST- und GET-Daten von unerwünschten Zeichen befreit (für ein Gästebuch & eine Kommentarfunktion).
Da der Text ja dann im SQL-Befehl landet frage ich lieber ein paar Profis, die mit SQL Injections mehr Erfahrung haben ;)

PHP:
function bereinigen($Text) {

	// Leerzeichen am Anfang und Ende beseitigen
	$Text = trim($Text);

	// HTML-Tags maskieren
	$Text = htmlspecialchars($Text, ENT_QUOTES);

	return $Text; // nur zum Testen, sonst nutze ich array_walk für POST & GET
}

magic_quotes_gpc ist aktiv, weshalb ja ' und " bereits mit einem \ davor versehen werden.

Wäre die Funktion so ok, oder sollte ich den eingegebenen Text noch um andere Zeichen beschneiden, damit niemand unerwünschten Code einschleusen kann?

Danke schon einmal für helfende Tipps. :)

Gruss sabermaul
 
Zuletzt bearbeitet:
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Ich nutze folgende Funktion um wirklich alle Usereingaben zu sichern:
PHP:
function inputSecurity($validate=null) {
	if ($validate == null) {
		foreach ($_REQUEST as $key => $val) {
			if (is_string($val)) {
				$_REQUEST[$key] = htmlentities($val);
			} else if (is_array($val)) {
				$_REQUEST[$key] = inputSecurity($val);
			}
		}
		foreach ($_GET as $key => $val) {
			if (is_string($val)) {
				$_GET[$key] = htmlentities($val, ENT_COMPAT, 'UTF-8');
			} else if (is_array($val)) {
				$_GET[$key] = inputSecurity($val);
			}
		}
		foreach ($_POST as $key => $val) {
			if (is_string($val)) {
				$_POST[$key] = htmlentities($val, ENT_COMPAT, 'UTF-8');
			} else if (is_array($val)) {
				$_POST[$key] = inputSecurity($val);
			}
		}
	} else {
		foreach ($validate as $key => $val) {
			if (is_string($val)) {
				$validate[$key] = htmlentities($val, ENT_COMPAT, 'UTF-8');
			} else if (is_array($val)) {
				$validate[$key] = inputSecurity($val);
			}
			return $validate;
		}
	}
}
Die Funktion ohne Parameter aufgerufen ergibt, dass alle Strings und alle Strings, die in einem Array in einer der Variablen $_POST, $_GET, $_REQUEST auftaucht, escapet werden. Wenn man einen String oder Array übergibt, werden alle untergeordneten Strings escapet. Musst ggf. den Zeichensatz ändern, falls du kein UTF-8 verwendest.

Zum Speichern in der Datenbank würde ich PDO verwenden und nicht mehr die nativen mysql Funktionen von PHP. Magic Quotes würde ich aber deaktivieren, das führt sonst zu Salat wenn doppelt escapet wird.
 
Danke für deinen Beitrag.
Ich hab schon viel über PDO gelesen und gesucht, jedoch nirgends eine gescheite Anleitung gefunden, die den Einstieg erleichtert (ich bin halt mysql_query gewohnt^^). Kennst du da eine Seite außer php.net?
 
Ich bin mit http://php.net/PDO eigentlich ganz gut klar gekommen. Das sieht aber auch ganz gut aus zur Einführung:
http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html

Das Wichtigste ist das Connecten, Prepared Statements, der Unterschied zwischen bindParam() und bindValue() und atomare Transaktionen. Wenn man es einmal verstanden hat, ists genauso einfach wie die alten Funktionen zu benutzen. Der größte Unterschied ist, dass man nicht mehr einfach die SQL Anweisung mit den Userdaten konkateniert, sondern dass man wiederverwendbare SQL-Querys hat, deren Variablen man einfach neu setzen und wieder ausführen kann. Man braucht zwar ein paar mehr Zeilen um eine komplette Query auszuführen, dafür sind SQL Injections aber ausgeschlossen und man gewinnt teilweise sogar an Performance, weil die Prepared Statements voroptimiert werden.

Da PDO komplett objektorientiert arbeitet, ist es übrigens auch ein guter Einstiegspunkt, um Objektorienterung in PHP zu lernen und möglichst konsequent umzusetzen. ;)
 
Danke für den Link!

In der letzten Stunde in DV wurden wir über Objekte aufgeklärt (wir lernen dieses Jahr Java kennen - nach ASP wird das schon eine Umstellung^^), von daher sollte das nicht das Problem sein.
 
das objektmodel von php ist ja auf das noetigste runtergedampft und daher schnell gelernt.

Ich finde es etwas befremdlich htmlspecialchars() bzw. htmlentities() als filter fuer input parameter zu verwenden. Das sind ja eigentlich Methoden zum maskieren von Output. Ich moechte ja normalerweise mit dem originalen Userinput weiterarbeiten und nicht mit ohne meine Einwirkung geaenderten Daten. Ausserdem kann es ja schon gewuescht sein zb oeffnende und schliessende spitze Klammern in der Datenbank zu speichern.
Zum Filtern von Userinput wuerde ich auf die filter funktionalitaet von php zurueckgreifen.

infinity: Deine Methode vergisst den $_FILES Sondernfall. Ueber den Dateinamen kann ja auch versucht werden Schadcode einzufueren. Und statt den ganzen foreaches wuerde sich ein array_walk_recursive anbieten.

Und zum Speichern in der Datenbank: Es ist auf jeden Fall eine sehr gute Idee PDO zu verwenden. Noch besser ist es IMHO aber noch eine Abstraktionsebene dazwischenzuschalten und ein Framework zu werden das sich um alles kuemmert.
 
Zuletzt bearbeitet:
Ich moechte ja normalerweise mit dem originalen Userinput weiterarbeiten und nicht mit ohne meine Einwirkung geaenderten Daten. Ausserdem kann es ja schon gewuescht sein zb oeffnende und schliessende spitze Klammern in der Datenbank zu speichern.
Ja richtig, ich habs auch dazu benutzt, dass es dem User nicht möglich ist, HTML und Scriptcode einzuschleusen. Wenn man direkt alle Usereingaben filtert, kann es nicht passieren, dass eine Sicherheitslücke entsteht, weil man irgendwo vergessen hat, die Ausgabe zu filtern. Dass User HTML eingeben können/dürfen/sollen ist ja eher die Ausnahme.

infinity: Deine Methode vergisst den $_FILES Sondernfall. Ueber den Dateinamen kann ja auch versucht werden Schadcode einzufueren.
Stimmt, sollte man ergänzen, wenn man Dateiuploads braucht. :)
 
z.b. dass im besten Fall immer eine mysql verbindung da sein sollte.
 
Aber wenn man eine Abfrage stellt dann braucht man so oder so eine Verbindung.
Also Verbindung herstellen, realescapen, Abfrage starten. Oder seh ich das falsch?
 

1. Es sichert keine Usereingaben vor schädlichem Code ab.
2. Man kann es vergessen.
3. Kein schädlicher Output wird dadurch gefiltert. mysql_real_escape_string() formt die Eingabe nur so um, dass die Ausgabe in SQL-Anfragen sicher verwendet werden kann. Nicht mehr, nicht weniger.

Jemand könnte dann trotzdem soetwas wie <script src="http://boeseseite.com/boesesscript.js" type="text/javascript" /> auf deine Seite posten und das würde beim User ausgeführt werden.
 
Aber wenn man eine Abfrage stellt dann braucht man so oder so eine Verbindung.
Also Verbindung herstellen, realescapen, Abfrage starten. Oder seh ich das falsch?
ja, wenn. Es soll aber durchaus seiten geben die ohne MySQL arbeiten.

Stimme da infinity_dev von seinen Argumenten her zu, auch wenn ich persoenlich seine Loesung nicht fuer sinnvoll erachte (aber das ist ein anderes Thema). mysql_real_escape_string hat sein einsatzgebiet schon im namen. dinge die in die mysql datenbank sollen escapen. und dafuer sollte man es einsetzen. gegen xss bietet es zb. keinen schutz
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh