Forum: PC-Programmierung SQL-Injection, Anfrageformulare php


von Mike M. (mikeii)


Lesenswert?

Hi,

und zwar hab ich eine Frage zur SQL Injection.
Da ich prüfen wollte, ob das Formular durch die mysql_real_escape_string 
Funktion sicher ist, wollte ich erst ohne diese Funktion versuchen, den 
Inhalt der Datenbank zu löschen.
Bin aber daran gescheitert, da Magic Quotes aktiviert waren.

Jetzt die Frage, reichen Magic Quotes in der Regel aus um eine SQL 
Injection zu verhindern, oder gibt es da einen weg drumherum?


Mein anderes Anliegen wäre, wie man sich davor schützen kann, dass ein 
User pro Tag mehr als z.B. 10 Formulare abschickt, wenn die IP als 
Kriterium ausscheidet (z.B. wegen eine Firma mit über 100 
Arbeitsplätzen, welche alle die gleiche Internet IP haben).

von Troll (Gast)


Lesenswert?

Mike Mike schrieb:
> Jetzt die Frage, reichen Magic Quotes in der Regel aus um eine SQL
> Injection zu verhindern, oder gibt es da einen weg drumherum?

Nein! Magic-Quotes waren eine Bastelei aus früheren PHP-Versionen fliegt 
zum Glück mit der aktuellen PHP 5.4 raus. Zum sichern der Daten für die 
DB wird mysql(i)_real_escape_string benutzt.

Mike Mike schrieb:
> Mein anderes Anliegen wäre, wie man sich davor schützen kann, dass ein
> User pro Tag mehr als z.B. 10 Formulare abschickt

Cookies. Sonst gibts noch Möglichkeiten mit User Agent, Plugins, 
Sprache, usw. eine halbwegs eindeutige Kennung zu erzeugen. Wirklich 
sicher kannst du es nicht verhindern.

von Patrick (Gast)


Lesenswert?

Mike Mike schrieb:
> reichen Magic Quotes in der Regel aus um eine SQL
> Injection zu verhindern

Nö. Damit wird ja z. B. kein Semikolon ersetzt -> Das Ding ist offen wie 
ein Scheunentor (in Überbreite).

Übrigens haben es sogar die PHP-Entwickler inzwischen (nach nur... 
achje, ich vermag die Jahre nicht mehr zu zählen) eingesehen, dass Magic 
Quotes eine Verschlimmbesserung und Pfusch höchsten Grades sind; daher 
sind die neuerdings auch nicht mehr vorhanden...

Prepared Statements sind das, was Du brauchst. Bitte benutze eine der 
zahlreichen (seufz) aktuell(er)en MySQL-Schnittstellen von PHP, 
meinetwegen MySQLi. Oder benutze nach Möglichkeit eine andere 
Programmiersprache (ist leider ernst gemeint).

von mikeii (Gast)


Lesenswert?

Ok Prepared Statement ist eine Möglichkeit, aber ist 
mysql_real_escape_string nicht ausreichend?

Und was heißt aktuellere Schnittstelle, ich hab bisher nur die 
Standartschnittstelle verwendet, was ist mit der nicht in ordnung?

Danke

von TestX .. (xaos)


Lesenswert?

mikeii schrieb:
> Ok Prepared Statement ist eine Möglichkeit, aber ist
> mysql_real_escape_string nicht ausreichend?
>
> Und was heißt aktuellere Schnittstelle, ich hab bisher nur die
> Standartschnittstelle verwendet, was ist mit der nicht in ordnung?
>
> Danke

PDO und preapred statements..das ist stand der technik..

von Patrick (Gast)


Lesenswert?

mikeii schrieb:
> ist mysql_real_escape_string nicht ausreichend?

Naja, ich sage mal, es ist besser als nichts ;)
Zu beachten wäre z. B., dass mysql_real_escape_string das Character Set 
der aktuellen Verbindung nimmt -> Leichtsinnsfehler vorprogrammiert.

mikeii schrieb:
> ich hab bisher nur die
> Standartschnittstelle verwendet, was ist mit der nicht in ordnung?

Naja, die ist inzwischen nicht mehr standardmäßig aktiviert, und die 
PHP-Entwickler schreiben auch: "This extension is not recommended for 
writing new code."

Alles in Allem halte ich derartige Low-Level-APIs (ist ja im Grunde nur 
ein sehr dünner Wrapper um die libmysql) einfach nicht mehr für 
zeitgemäß. So konnte man vielleicht vor zehn Jahren noch arbeiten, zu 
einer Zeit, als HTML 3, JavaScript, PHP 3, SQL usw. wild 
durcheinandergewürfelt wurden - aber, bitte, bitte, wenn Du etwas Neues 
programmierst, schreibe den Code bitte halbwegs "state of the art", d. 
h. eigensicher (mit PHP stellenweise gar nicht mal so einfach - z. B. 
Stichwort "Unterschiedliches Verhalten, je nachdem, ob Magic Quotes auf 
dem Server aktiviert sind oder nicht") und halbwegs strukturiert. Muss 
ja nicht gleich ein MVC-Framework Einzug halten, aber zumindest die 
objektorientierte MySQLi-Schnittstelle würde ich schon empfehlen.

von Patrick (Gast)


Lesenswert?

Andi D. schrieb:
> PDO und preapred statements..das ist stand der technik..

Naja... Stand der Technik ist es eigentlich, PHP durch eine vernünftige, 
zeitgemäße Skriptsprache zu ersetzen - okay, okay, ich bin ja schon 
wieder leise, bevor ich noch den Zorn der Mitforisten auf mich lenke ;)

von D. I. (Gast)


Lesenswert?

Patrick schrieb:
> Andi D. schrieb:
>> PDO und preapred statements..das ist stand der technik..
>
> Naja... Stand der Technik ist es eigentlich, PHP durch eine vernünftige,
> zeitgemäße Skriptsprache zu ersetzen - okay, okay, ich bin ja schon
> wieder leise, bevor ich noch den Zorn der Mitforisten auf mich lenke ;)

Ruby on Rails

von Mike M. (mikeii)


Lesenswert?

So, ich hab mal Mysqli und PS verwendet. Das Problem ist, ich bekomme 
das Prepared Statement nicht zu stande. Ich bekomme jedesmal false 
zurück, was bedeutet, dass das PS nicht angenommen wird.
1
$stmt = $connection->prepare("INSERT INTO anfragen (betreff, anfrage, name, email, telefon, prioritaet, datum, zeit) 
2
                              VALUES (:betreff, :anfrage, :name, :email, :telefon, :prioritaet, :datum, :zeit)");
3
var_dump($stmt);

Als Fehlermeldung:

bool(false)
Fatal error: Call to a member function bindParam() on a non-object in 
/.../send.php on line 42

Die Attribute der Tabelle sind folgende:

id        int         AI
betreff      varchar
anfrage      varchar
name        varchar
email        varchar
telefon      varchar
prioritaet   int
datum        date
zeit        time
absender     varchar
domaine      varchar
id_notitz    varchar
lastchanged  timestamp   ON UPDATE CURRENT_TIMESTAMP


edit

Fehler gefunden, Verbindungsaufbau geht mit $connection = new 
mysqli($dbhost, $dbuser, $dbpasswd); und nicht mit $connection = 
@mysqli_connection($dbhost, $dbuser, $dbpasswd);


Trotzdem wird die DB nicht befüllt, aber das muss ich erstmal selber 
suchen

von Mike M. (mikeii)


Lesenswert?

So bevor hier was falsche steht, bitte vergesst das obere.
Mysqli und Mysql sind total verschieden, daher die Fehler!

Hier mal der Code, wie es wirklich funktioniert:
Ist gekürzt und ohne Fehlerbehandlung, nur das Prinzip:
1
$mysqli = new mysqli($dbhost, $dbuser, $dbpasswd);
2
$mysqli->select_db($dbname);
3
$stmt = $mysqli->prepare("INSERT INTO anfragen (betreff, anfrage, name, email, telefon, prioritaet, datum, zeit) 
4
                          VALUES (?,?,?,?,?,?,?,?)");
5
$stmt->bind_param("sssssiii",$anfrage, $betreff, $name, $email, $telefon, $prioritaet, $datum, $zeit);
6
$stmt->execute();
7
mysqli_close($mysqli);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.