Gestäbuch absicher UND Affenformular
bleicher
- programmiertechnik
0 Mega0 Ingo Turski
Grüße,
derzeit tüftle ich am Gästebuch dabei stieß ich auf folgendes problem - wenn ich die daten in einem getrennten script verarbeite, verhindere ich wiederholtes absenden des formulars beum neuladen der Seite.
andererseits macht es den affenformular eine komplexere angelegenheit (oder was habe ich nicht bedacht?) da ich ja die post-daten nicht ohne weiteres beim rückleiten erneut mitschicken kann, um die im affenformular darzustellen.
ich löse es momentan mit $_SESSION, was mir aber nicht SO eine saubere lösung zu sein scheint.
gäbe es eine bessere?
ah ja - ich habe mich so gut ich konnte gegen insertions abgesichert - aber wäre jemadn trotzdem so nett an den "üblichen" stäben zu rütteln? man kann ja nicht alles im auge behalten :P
MFG
bleicher
gäbe es eine bessere?
Wie wäre es mit nem Hidden-Feld und einem Zufallsstring? Würde die Session sparen und du hast kein Problem, wenn jemand Cookies deaktiviert hat.
Liebe(r) Mega,
Wie wäre es mit nem Hidden-Feld und einem Zufallsstring? Würde die Session sparen und du hast kein Problem, wenn jemand Cookies deaktiviert hat.
ich finde die Kombination aus Zufalls-String _und_ Session optimal. Damit wäre der Zufallsstring in der Session eintragbar, um ihn als Schlüssel-Schloss-Mechanismus zu benutzen. Jedenfalls funktioniert dieses Vorgehen bei mir schon seit geraumer Zeit zuverlässig.
Übrigens ist der Session-Mechanismus von PHP nicht auf Cookies festgelegt. Das macht ihn so variabel einsetzbar, da alternativ auch ein $_GET-Parameter eingesetzt werden kann.
Liebe Grüße,
Felix Riesterer.
Grüße,
Wie wäre es mit nem Hidden-Feld und einem Zufallsstring? Würde die Session sparen und du hast kein Problem, wenn jemand Cookies deaktiviert hat.
ich finde die Kombination aus Zufalls-String _und_ Session optimal. Damit wäre der Zufallsstring in der Session eintragbar, um ihn als Schlüssel-Schloss-Mechanismus zu benutzen. Jedenfalls funktioniert dieses Vorgehen bei mir schon seit geraumer Zeit zuverlässig.
zufallsstring im hiddenfeld? und was ist der schloß dann? der letzte eintrag?
Übrigens ist der Session-Mechanismus von PHP nicht auf Cookies festgelegt. Das macht ihn so variabel einsetzbar, da alternativ auch ein $_GET-Parameter eingesetzt werden kann.
ist aber leider serverkonfigurationssache, oder?
MFG
bleicher
Lieber bleicher,
zufallsstring im hiddenfeld? und was ist der schloß dann? der letzte eintrag?
"Der" Schloss ist das, was im name-Attribut steht. Beispiel:
<input name="Zufallswert1" value="Zufallswert2">
In der Session steht dann, dass $_POST['Zufallswert1'] nach dem Absenden existieren muss und dass es unbedingt 'Zufallswert2' enthalten muss - sonst wird der Eintrag nicht angenommen (sondern z.B. eine erneute(?) Vorschau angezeigt).
Übrigens ist der Session-Mechanismus von PHP nicht auf Cookies festgelegt. Das macht ihn so variabel einsetzbar, da alternativ auch ein $_GET-Parameter eingesetzt werden kann.
ist aber leider serverkonfigurationssache, oder?
Wer lesen kann, ist klar im Vorteil...
Liebe Grüße,
Felix Riesterer.
Grüße,
In der Session steht dann, dass $_POST['Zufallswert1'] nach dem Absenden existieren muss und dass es unbedingt 'Zufallswert2' enthalten muss - sonst wird der Eintrag nicht angenommen (sondern z.B. eine erneute(?) Vorschau angezeigt).
du meinst, dass ich die gleichen werte in die session schreibe?
da kann man doch ein schritt weiter gehen, und einfach nur $_SESSION['schonkommentiert'] benutzen - es verhindert auch z einfaches sapmmen.
das mit SID am url - ich weiss echt nicht, wie mein mod_rewrite darauf reagiert >:( so wirds wohl nicht gehen.
aber gut bestätigt zu haben, dass es nicht möglich ist die SID automatisch an die urls anhängen zu lassen ;/
MFG
bleicher
Lieber blajschärr,
In der Session steht dann, dass $_POST['Zufallswert1'] nach dem Absenden existieren muss und dass es unbedingt 'Zufallswert2' enthalten muss - sonst wird der Eintrag nicht angenommen (sondern z.B. eine erneute(?) Vorschau angezeigt).
du meinst, dass ich die gleichen werte in die session schreibe?
da kann man doch ein schritt weiter gehen, und einfach nur $_SESSION['schonkommentiert'] benutzen - es verhindert auch z einfaches sapmmen.
zak sh droch!
das mit SID am url - ich weiss echt nicht, wie mein mod_rewrite darauf reagiert >:( so wirds wohl nicht gehen.
Tja, dann hast Du irgendwo in Deinem Script einen Fehler. Die SID ist ein gewöhnlicher URL-Parameter, der beim ersten Mal übertragen werden muss, denn der Server weiß beim ersten Kontakt noch nicht, ob Cookies akzeptiert werden.
aber gut bestätigt zu haben, dass es nicht möglich ist die SID automatisch an die urls anhängen zu lassen ;/
Du hast entweder die Doku nicht gelesen, oder nicht verstanden. Es existiert session.use_trans_sid, was die SID automatisch an entsprechende URLs anhängt - in meinen Scripten stört das allerdings, sodass ich das Teil nach Möglichkeit abstelle.
UND: Die SID ist ein Automatismus. Wenn Cookies akzeptiert werden, ist SID ein Leerstring und stört nicht weiter.
Liebe Grüße,
Felix Riesterer.
Grüße,
die php.net docu ist leider nicht DIE referenz ;/ ich habe gegoogelt, und wie es ausseiht ist die option derzeit irrelevant - da mein lieber freehoster die nicht anbietet. (in .htaccess nicht, und zu ini hab ich ja kein zugriff)
MFG
bleicher
p:S. obwohl ein anderer hoster schon -
byethost.com <-falls jemand eine testplatform braucht
MFG
bleicher
hi,
ich steh seit 2 Tagen vor dem selben Problem.
"Der" Schloss ist das, was im name-Attribut steht. Beispiel:
<input name="Zufallswert1" value="Zufallswert2">
In der Session steht dann, dass $_POST['Zufallswert1'] nach dem Absenden existieren muss und dass es unbedingt 'Zufallswert2' enthalten muss - sonst wird der Eintrag nicht angenommen (sondern z.B. eine erneute(?) Vorschau angezeigt).
Wie muss diese Prüfung aussehen?
Ich hab folgenden Ansatz verfolgt aber ich weiss einfach nicht, wie ich die Prüfung mache, ob schon was gesendet wurde.
/** User Initialisieren und in input hidden[form] speichern
*
* Wenn es einen $_POST-Request gibt, den zu beginn
* initialisierten Wert als einmalige ID speichern
*/
mt_srand ( (double)microtime () * 1000000 );
$user_id = md5( mt_rand () );
if(isset($_POST["form"]) AND (preg_match('/^[a-f0-9]{32}$/',$_POST["form"])))
{
$user_id = $_POST["form"];
}
$my_user_id = htmlspecialchars($user_id);
/** HTML Ausgabe <<<EOT
* <input type="hidden" name="form" value="$my_user_id" />
* EOT;
*/
/**
* Prüfen, ob während der Eingabe ein Fehler auftrat
* $error_flag wird während der Validation der Usereingaben entsprechend gesetzt
*/
if($_POST)
{
foreach($mein_formbuild_array as $mailRoutine_key)
{
$MyErrorFlag .= (!empty($error_flag[$mailRoutine_key['Feldname']]))
? $error_flag[$mailRoutine_key['Feldname']]
: '' ;
}
}
/**
* Wenn alles Ok ist, Submit-Button einblenden um das absenden zu ermöglichen
*/
if(($_POST) AND (empty($MyErrorFlag)))
{
$SendeButton = '<input type="submit" class="SendButton" name="submit" value="Abschicken" />';
if((isset($_POST['submit'])) AND ($_POST["form"] == $my_user_id))
{
unset($_POST); // $_POST leeren
$SendeButton = ''; // Submit-button wieder ausblenden
}
}
Wie muss ich hier vorgehen?
Script im Einsatz, es wird keine Mail verschickt, die Seite dient nur testzwecken.
mfg
Lieber Malcolm,
1. Du startest eine Session.
2. In dieser Session hast Du eventuell schon Werte drin (wenn ein Besucher z.B. etwas abschickt, dann hat er vorher das Formular abgeholt und Cookie bekommen)
- wenn schon vorhanden, dann übernehmen, falls nicht, neu anlegen:
~~~php
$_SESSION['schloss'] = $zufallswert1;
$_SESSION['schluessel'] = $zufallswert2;
3\. Du überprüfst, ob bestimmte $\_POST-Indices (z.B. `]$_POST['aktion'] == "auswerten"`{:.language-php}) vorhanden sind, falls ja -> Auswerten, falls nein -> Formular neu erstellen und ausgeben
4a. (neues Formular):
- neue Zufallswerte anlegen (für Schloss und Schlüssel)
- ein hidden-Feld erstellen, dessen name-Attribut den "Schloss"-Wert, und dessen value-Attribut den "Schlüssel"-Wert erhält
- ein spezielles hidden-Feld, an dem unser Script erkennt, dass ein Formular ausgewertet werden soll (z.B. `<input name="aktion" value="auswerten" type="hidden" />`{:.language-html} (da könnte man aber auch den submit-Button nutzen, dem man das name-Attribut entsprechend verpasst, allerdings ist das dann mit dem value-Prüfen so eine Sache...)
4b.(Auswertung)
- Die Session kennt ja `$_SESSION['schloss'] und $_SESSION['schluessel']`{:.language-php}, also wird geprüft:
`isset($_POST[$_SESSION['schloss']]) && $_POST[$_SESSION['schloss']] == $_SESSION['schluessel']`{:.language-php}
- Wenn obige Prüfung scheitert, dann wird 4a ausgeführt, und bereits eingegebene Userdaten im Formular voreingetragen.
Zusätzlich kann man ein Texteingabefeld mit einem "verräterischen" name-Attribut ins Formular aufnehmen, zu dem man schreibt, dass der User es leer lassen soll, um alles mit CSS dann aus dem sichtbaren Bereich zu "verschieben". Bots tragen etwas ein, Menschen nicht.
Prinzip klarer geworden? Näheres findest Du in meinem GB-SCript.
Liebe Grüße,
Felix Riesterer.
--
ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
hi Felix,
- Du startest eine Session.
Stimmt, dass gibt es ja auch noch, da hatte ich garnicht dran gedacht.
Da muss ich mich erstmal reinlesen, hab noch nie richtig mit Session gearbeitet.
Ich beziehe mich mal auf was ich nicht verstehe;
4b.(Auswertung)
- Die Session kennt ja$_SESSION['schloss'] und $_SESSION['schluessel']
, also wird geprüft:
isset($_POST[$_SESSION['schloss']]) && $_POST[$_SESSION['schloss']] == $_SESSION['schluessel']
Ist da jetzt ein schreibfehler drin oder lautet die Prüfung so?
Ich werde mich jetzt erstmal mal den Sessions widmen.
Zusätzlich kann man ein Texteingabefeld mit einem "verräterischen" name-Attribut ins Formular aufnehmen, zu dem man schreibt, dass der User es leer lassen soll
Effektive Spamabwehr ist kein Problem, nur das reloaden macht mir zu schaffen.
mfg
Grüße,
ich stehe hier ziemlich standhaft auf dem schlauch -. ich verstehe zwar was gemacht wird, aber nicht wozu.
es wird bei jedem aufruf der seite ein zufallswertpaar erzeugt, in ein hiddenformularfeld geschrieben, abgeschickt und mit sich selbst verlgeichen.
ich verstehe ehrlich gesagt nicht, in welchem fall die prüfung scheitert?
MFG
bleicher
Lieber bleicher,
ich stehe hier ziemlich standhaft auf dem schlauch
das ist auch was wert. ;-)
ich verstehe ehrlich gesagt nicht, in welchem fall die prüfung scheitert?
Die Grundidee ist sicherzustellen, dass ein _Mensch_ das Formular abschickt. Ein Mensch wird sich dieses Formular garantiert vom Server laden, ausfüllen und abschicken.
Ein Script geht anders vor. Es parst das Formular, ermittelt, wo es in welchen Feldern welche Inhalte eintragen muss, um das Formular dann abzuschicken.
Mit dem Session-Mechanismus wird garantiert, dass das bearbeitete Formular vorher vom Server angefordert wurde, die dort eingetragenen Zufallswerte auch von dieser Anforderung stammen, sodass beim Auswerten des abgeschickten Formulars diese Werte wieder "kommen" müssen. Ein Script generiert selbst viele Formulare (und die ursprünglichen Zufallswerte werden nur weiterkopiert, anstatt frisch mit dem Server abgeglichen), die unter Umständen auch ohne Session-Werte abgeschickt werden.
Damit werden also nur Formulare erfolgreich bearbeitet, die innerhalb derselben Session angefordert wurden (das wird einem Script schwer fallen), da sie sozusagen durch die Zufallswerte "signiert" sind. Mit einer ersten Zwangsvorschau (die ein Mensch kapiert, ein Script eher nicht) wird zusätzlich SPAM vermieden, da in der Vorschau natürlich wieder frische Zufallswerte enthalten sind, die auch in der Session neu eingetragen wurden, sodass ein simples doppeltes Abschicken des identischen Formulares scheitern muss.
Klarer geworden?
Liebe Grüße,
Felix Riesterer.
Grüße,
Klarer geworden?
ja ;) aber ich wusste nicht mal das bots in 2 durchgängen arbeiten und habe diese schutzmaßnahme erst für ein schutz gegen mehrfaches formularabsenden gehalten >:]
MFG
bleicher
Hi,
ja ;) aber ich wusste nicht mal das bots in 2 durchgängen arbeiten
Nein - unklarer. ;-)
Die meisten Bots arbeiten "live", dh. sie scannen das Formular, machen Ihne Einträge an den vermeintlich passenden Stellen und schicken die Formulardaten in durchschnittlich 1 bis 3 Sekunden ab. Einige davon schicken dann zwar mehrfach verschiede Spams direkt hintereinander, ohne das Formular erneut zu scannen (also Scan 09:05:14, 1. Spam 09:05:15, 2. Spam 09:05:15) - manchmal auch mit unterschiedlichen IPs und verschieden Feldauswahlen, aber die würden auch nicht von der Zufallszahl abgehalten werden.
"Faule" Bots, die ein Formular nur einmal scannen, sind demgegenüber sehr viel seltener - und wohl auch deutlich weniger erfolgreich.
freundliche Grüße
Ingo
Grüße,
Die meisten Bots arbeiten "live",
hm ;/
kann man die "blocken"?
ich kann mir denken, dass man den formular zB mit JS schreiben kann - und die user ohne JS kriegen dafür die captchas zu sehen.
oder beherrschen die mots mittlerweile auch JS?
MFG
bleicher
Lieber bleicher,
kann man die "blocken"?
[...]
oder beherrschen die mots mittlerweile auch JS?
bei meinem Vorgehen irrelevant.
Liebe Grüße,
Felix Riesterer.
Hi,
kann man die "blocken"?
natürlich. Mein Gästebuchscript blockt monatlich 3000 bis 6000 Spams zuverlässig. Ganz ohne Hürden für echte Besucher.
freundliche Grüße
Ingo
Lieber Ingo,
Die meisten Bots arbeiten "live", dh. sie scannen das Formular, machen Ihne Einträge an den vermeintlich passenden Stellen und schicken die Formulardaten in durchschnittlich 1 bis 3 Sekunden ab. Einige davon schicken dann zwar mehrfach verschiede Spams direkt hintereinander, ohne das Formular erneut zu scannen (also Scan 09:05:14, 1. Spam 09:05:15, 2. Spam 09:05:15) - manchmal auch mit unterschiedlichen IPs und verschieden Feldauswahlen, aber die würden auch nicht von der Zufallszahl abgehalten werden.
ich möchte Dir widersprechen. Die "Zufallszahlen" werden in einer Session vorgehalten. Existiert (noch) keine solche, werden jegliche "Zufallszahlen" aus einem abgeschickten Formular ignoriert, da ja keine Vorschau bisher bestätigt wurde und als HTTP-Antwort käme das Formular mit einer Vorschau (und neuen Zufallszahlen) an den Bot zurück - der das aber ignoriert.
Damit wird ein mehrfach-Abschicken erfolgreich geblockt, da die Session-Werte bei jedem Script-Aufruf geändert werden. Nur eine Race-Condition könnte die Bots aufhalten, _nachdem_ eine erste Vorschau erfolgreich vom Bot als Formular eingescannt wurde, sodass seine mehrfachen Aufrufe mit dieser Session so schnell am Server ankommen, dass in den verschiedenen Threads die Prüfung erfolgreich abgelegt wird, bevor die Zufallswerte geändert werden. Aber dazu muss ein Bot ersteinmal die erste Zwangsvorschau erfolgreich bestätigen... und daran scheitern sie bisher alle.
Liebe Grüße,
Felix Riesterer.
Hi,
ich möchte Dir widersprechen. Die "Zufallszahlen" werden in einer Session vorgehalten. Existiert (noch) keine solche, werden jegliche "Zufallszahlen" aus einem abgeschickten Formular ignoriert, da ja keine Vorschau bisher bestätigt wurde und als HTTP-Antwort käme das Formular mit einer Vorschau (und neuen Zufallszahlen) an den Bot zurück - der das aber ignoriert.
Damit widersprichst Du mir eigentlich gar nicht. Denn Du nutzt hier lediglich eine (über Session abgesicherte) Zwangsvorschau. Das ist eine relativ sichere, aber auch für den Besucher nervige Methode.
Damit wird ein mehrfach-Abschicken erfolgreich geblockt, da die Session-Werte bei jedem Script-Aufruf geändert werden.
Bist Du Dir da sicher bzw. was verstehst Du darunter? Wenn durch Refresh (unbeabsichtigt) die Formulardaten erneut übermittelt werden, sind dies die gleichen - zumindest wenn Cookies deaktiviert sind. Ich verhindere doppeltes abschicken ganz einfach durch Speicherung der letzten Eingaben auf dem Server. Für nicht extrem frequentierte Gästebücher reicht das völlig.
freundliche Grüße
Ingo
Übrigens ist der Session-Mechanismus von PHP nicht auf Cookies festgelegt. Das macht ihn so variabel einsetzbar, da alternativ auch ein $_GET-Parameter eingesetzt werden kann.
Stimmt, hab ich gar nicht mehr dran gedacht. Ist ja kein >Problem, ein Fallback zu nutzen. Ich mache es ja selber so ;)
Hi,
andererseits macht es den affenformular eine komplexere angelegenheit (oder was habe ich nicht bedacht?) da ich ja die post-daten nicht ohne weiteres beim rückleiten erneut mitschicken kann, um die im affenformular darzustellen.
ich nutze dazu eine ganz simple Methode - und da Gästebucheinträge recht selten sind, reicht die völlig aus.
freundliche Grüße
Ingo