PHP Sicher? Per Formular Daten in mysql eintragen

pin0cci0

Cadet 4th Year
Registriert
Jan. 2010
Beiträge
94
Hi!
Also ich bin gerade dabei mich ein bisschen mit php und mysql auseinanderzusetzen. Momentan geht es mir darum eine Email und einen beliebigen Begriff per Formular in meine Datenbank zu schreiben. Das funktioniert soweit auch ganz gut, allerdings habe ich bedenken, bezüglich der Sicherheit meines Scriptes... wie kann ich beispielsweise sql-injection und ähnliches abwehren?

Hier mein Script:
PHP:
<?php
if ($_POST[suchbegriff] && $_POST[mail]) {
	include("dbconnect.php"); //hier wird die verbindung zur datenbank aufgebaut, braucht ihr das script auch?
	$anfrage = $_POST["suchbegriff"];
	$email = $_POST["mail"];
	$eintrag = "INSERT INTO suchanfragen (email, anfrage) VALUES ('$anfrage', '$email')";
	$eintragen = mysql_query($eintrag);
	echo 'Die Suchanfrage wurde erfolgreich eingetragen!';
	echo '<html><head><meta http-equiv="refresh" content="3; url=http://meineseite.de"><title>Success!</title></head></html>';
	} else {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html>
<head>
<title>Formular</title>
</head>
<body>
<form action="<?php echo $PHP_SELF; ?>" method="post">
Suchbegriff:<br/>
<input type="text" name="suchbegriff" size=60 maxlength=120 value="<?php echo $suchbegriff ?>"><br />
eMail:<br />
<input type="text" name="mail" size=60 maxlength=120 value="<?php echo $mail ?>"><br />
<input type="submit" value="Anfrage speichern" name="submit"> 
</form>
<?php
}
?>
</body>
</html>


Vielen Dank schonmal!

Grüße pino
 
Hi

- Überprüfung der eingegebenen Daten per PHP
- mysql_real_escape_string() zur Vermeidung von SQL Injections - oder mysqli::real_escape_string (je nachdem ob evt. nicht doch lieber auf
mysqli anstelle mysql_... zurückgegriffen wird).
 
regex, htmlspecialchars- und tities für sonderzeichen und umlaute gegen xss würde mir spontan noch einfallen.
 
Wenn du einen "richtigen" Server oder einen vServer hast könntest du noch eine Web Application Firwall (WAF) installieren. Die WAF prüft alle eingehenden Requests anhand festgesetzer Regeln und wenn was verdächtig erscheint wird der Request blockiert bevor er noch vom Apache verarbeitet wird.

Ansonsten sollltest du (sofern verwendet) auch Werte die du aus Cookies ausliest mit berücksichtigen.
 
okay, vielen Dank schonmal für eure Antworten. geändert habe ich bis jetzt das:

PHP:
$anfrage = mysql_real_escape_string($_POST["suchbegriff"]);
	$email = mysql_real_escape_string($_POST["mail"]);

wie soll ich denn die daten "per php überprüfen"?

habe leider keinen vserver...:(
 
Du kannst bspw. prüfen, ob gültige Zeichen eingegeben wurden.

Ein Name darf bspw. keine Ziffer enthalten, die Email-Adresse muss ein @-Zeichen enthalten usw. Das ist natürlich nicht zwingend notwendig, du kannst dem Absender so aber gleich eine Rückmeldung geben, wenn irgend etwas falsch eingegeben wurde oder auch Spammer abhalten, die irgendeinen Unsinn eintragen.
 
@snoot: Richtig - Plausibilitätsprüfungen sind unabdingbar um Falschdaten von vornherein auszuschließen.
 
Für das Feld "Suchbegriff" solltest du noch htmlentities() anwenden, damit kein Bösewicht auf die Idee kommt dir HTML Code unterzuschieben. So ein Cross-Site-Scripting und Cross-Site-Request-Forgery kann fatale Folgen haben.
Für die Prüfung einer gültigen E-Mail Adresse eignen sich Reguläre Ausdrücke. Wenn du damit noch nicht viel getan hast, dann wird es dir erstmal sehr kryptisch vorkommen, später wirst du sie lieben. ;-)

Für E-Mails nutze ich derzeit folgenden Schnipsel:
PHP:
preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/is',$email);
Der Audruck prüft ob eine E-Mail im Lokalteil nur a-z0-9 _ . - beinhaltet, dann muss ein @ kommen. Gefolgt von einer Domain, welche nur aus a-z . und - bestehen darf (hm, da fällt mir grad auf, dass damit Umlautdomains auch gültig sind.. diesen Rotz braucht doch keiner..) und am Ende ein . gefolgt von der TLD sein muss, welche zwischen 2 und 6 Zeichen haben darf. Das "is" ist nur dafür da, dass alles als ein String gesehen wird, welcher case-insensitive ist.
 
Hey! Danke euch für die Antworten.

S3PSiS: Hab deinen Eintrag leider ein bisschen zu spät gelesen. Habs jetzt so realisiert:
PHP:
<?php
if ($_POST[suchbegriff] && $_POST[mail]) {
	// Verbindung aufbauen
	mysql_connect("localhost", "xxx","xxx") or die
    ("Keine Verbindung moeglich");
	mysql_select_db("xxx") or die
    ("Die Datenbank existiert nicht.");
	
	if (preg_match("/[^a-zA-Z0-9ß\s]/", $_POST["suchbegriff"]) || preg_match("/[^a-zA-Z0-9ß.@]/", $_POST[mail]) || !preg_match("/@./", $_POST[mail]))
	{
	echo 'Fehlerhafte Eingabe!';
	echo '<html><head><meta http-equiv="refresh" content="2; url=http://meineseite.de/check"><title>Fehler! | MeineSeite.de</title></head></html>';
	}
	else {
	$anfrage = mysql_real_escape_string($_POST["suchbegriff"]);
	$email = mysql_real_escape_string($_POST["mail"]);
	$eintrag = "INSERT INTO suchanfragen (anfrage, email) VALUES ('$anfrage', '$email')";
	$eintragen = mysql_query($eintrag);
	echo 'Die Suchanfrage wurde erfolgreich eingetragen!';
	echo '<html><head><meta http-equiv="refresh" content="3; url=http://meineseite.de/check"><title>Success! | MeineSeite.de</title></head></html>';
	}
	} else {
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html>
<head>
<title>Formular | MeineSeite.de</title>
</head>
<body>
<form action="<?php echo $PHP_SELF; ?>" method="post">
Suchbegriff:<br/>
<input type="text" name="suchbegriff" size=20 maxlength=120 value="<?php echo $suchbegriff ?>"><br />
eMail:<br />
<input type="text" name="mail" size=30 maxlength=120 value="<?php echo $mail ?>"><br />
<input type="submit" value="Anfrage speichern" name="submit"> 
</form>
<?php
}
?>
</body>
</html>

Dabei ist dann doch htmlentities() irrelevant, weil < bzw. eigentlich alle Sonderzeichen nicht erlaubt sind....oder?

Ist der Code ansonsten jetzt so tauglich?

Vielen Dank und schöne Grüße

P.S. Habe ein anderes Script was alle 5min aufgerufen wird und die Daten wieder aus der Datenbank abruft und mit einem String vergleicht. Dieses Script ist doch nicht gefährdet, weil es von niemandem direkt aufgerufen wird und man keine Eingaben machen kann...oder?
 
Zuletzt bearbeitet:
Beim Suchbegriff (und theoretisch in der E-Mail) müsstest du noch gesondert Umlaute hinzufügen.

Da sollte dir einfach \w genügen
http://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck#Vordefinierte_Zeichenklassen schrieb:
\w: ein Buchstabe, eine Ziffer oder der Unterstrich, also [a-zA-Z_0-9] (und evtl. weitere Buchstaben, z. B. Umlaute)
 
So halb funktionieren tut deine Möglichkeit, nur kannst du damit auch falsche Mail-Adressen nutzen (Bsp: @test).

@Mr. Snoot: Recht hast du. Mit einem \i kann er auch noch die Groß- und Kleinschreibung ignorieren. Ein "s" dazu schadet auch nie.

Ein "w" Modifier gibt es meines Wissens nach nicht bei PHP. Ein \w liefert zumindest einen Fehler und ich kenne keine Alternative, aber kann gut sein, dass es da etwas gibt. siehe auch: http://www.php.net/manual/de/reference.pcre.pattern.modifiers.php

@Topic: Wie bereits gesagt, funktioniert deine Möglichkeit auch. Ist zwar alles nicht sehr elegant, aber erfüllt seinen Zweck. Gib den Matcher noch ein /is hinten mit und füg noch Sonderzeichen hinzu, sofern du das möchtest.

Dein <?php echo $suchbegriff; ?> und <?php echo $mail; ?> dürften nicht funktionieren, außer du hast vor deinem geposteten Code-Schnipsel die Variablen zugewiesen.
Funktioniert das auch ohne Zuweisung, dann solltest du register_globals auf "off" setzen. siehe dazu http://php.net/manual/de/security.globals.php (geht zum Beispiel per ini).
 
hey! also phpinfo sagt, dass register_globals aus ist. zugewiesen habe ich nichts (das ist der komplette code) und alles funktioniert so wie es soll. komisch...

\i und sonderzeichen tu ich noch dazu(einfach äöü schreiben?) \s hab ich ja schon und bei email brauch ich ja kein \s..oder?


mit register_globals versteh ich nicht..

sonst noch anregungen?

grüße pino
 
Hm, okay. Wüsste grad nicht, warum es trotz register_globals=off trotzdem geht, aber sollte nicht tragisch sein (hoff ich für dich ;-)).

Stimmt, bei der E-Mail brauchst du kein "s", aber bei deinem Suchbegriff ist der Modifier falsch gesetzt.
Richtig wäre:
PHP:
preg_match("/[^a-z0-9ßäöü]/is", $_POST["suchbegriff"])
Die Modifier kommen immer ans ganz ans Ende.

Und ja, äöü kannste einfach hinzufügen, beim ß hat's ja auch so funktioniert. :-)
 
hey, danke für die schnelle antwort. wenn ich jedoch
PHP:
preg_match("/[^a-z0-9ßäöü]/is", $_POST["suchbegriff"])

setze, funktioniert das "s" anscheinend nicht, denn Suchbegriffe mit Leerzeichen sind dann nicht mehr möglich...

edit: was genau besagt der mofifier "s" genau? zeilenumbrüche brauch ich ja nicht...ich brauche eigentlich nur leerzeichen...kann ich dann nicht einfach ein leerzeichen mit zu äöü schreiben und "s" weglassen? wäre das nicht sicherer?

edit2: hab jetzt das "s" weggelassen und einfach ein " " eingefügt. Klappt alles so wie es soll. Damit ist für mich das Thema eigentlich erledigt, falls nicht doch noch jemand irgendetwas gefährlich findet (hab jetzt auch reCaptcha eingebaut ;)

Vielen Dank für die Hilfe! Super Forum!

Grüße pino
 
Zuletzt bearbeitet:

Ähnliche Themen

K
Antworten
7
Aufrufe
6.569
Antworten
6
Aufrufe
1.473
mambokurt
M
E
Antworten
17
Aufrufe
1.480
E
Zurück
Oben