Das Website Change Request Form ist hier schon seit einiger Zeit ein Dauerthema, und ich werde es noch eine Weile weiterverfolgen. Wir werden nicht das gesamte HTML und JavaScript, das das Formular zum Laufen bringt, wiederholen, also wenn Sie aufholen müssen, schauen Sie sich den ersten Artikel an.
Was wir bisher haben, ist ein ziemlich gut aussehendes Formular mit einer ziemlich guten Benutzererfahrung. Ich finde jedoch, dass ihm zwei wichtige Dinge fehlen. A) Die Benachrichtigungs-E-Mails selbst sind eher blasse und einfache Text-E-Mails und B) es gibt fast keinerlei Sicherheit im Formular selbst.
Dank Daniel Friedrich habe ich nun einige ernsthaftere Sicherheitsmaßnahmen in das Formular integriert, und das wird der Schwerpunkt dieses Artikels sein. Die beiden großen Ziele sind:
- Das Formular wird von einem Menschen eingereicht
- Dieser Mensch tut nichts Böswilliges

Token-Abgleich
Als erstes werden wir einen „Token“ generieren, im Wesentlichen einen geheimen Code. Dieser Token wird Teil unserer „Session“ sein, was bedeutet, dass er serverseitig gespeichert wird. Dieser Token wird **auch** als verstecktes Eingabefeld in das Formular selbst eingefügt, wenn es im Browser generiert wird. Das bedeutet, dass dieser Token **sowohl** auf der Client-Seite als auch auf der Server-Seite existiert und wir sie abgleichen können, wenn das Formular übermittelt wird, um sicherzustellen, dass sie übereinstimmen. Dies stellt sicher, dass jede Übermittlung des Formulars **unser Formular** ist und kein Skript von Drittanbietern, das von einem anderen Server aus auf uns einstürmt.
Zuerst müssen wir eine Session starten, dann eine Funktion zum Erstellen des Tokens erstellen, ihn der Session zuweisen und ihn für unsere Nutzung zurückgeben.
session_start();
function generateFormToken($form) {
// generate a token from an unique value
$token = md5(uniqid(microtime(), true));
// Write the generated token to the session variable to check it against the hidden field when the form is sent
$_SESSION[$form.'_token'] = $token;
return $token;
}
Der einzigartige Wert hier stammt von einem md5-Hash der microtime-Funktion, aber Daniel sagt, es gibt eine Reihe anderer Verschlüsselungsmethoden (wie Salt-Werte...). Sobald wir diese Funktion haben, können wir sie kurz bevor wir das Formular im Markup erstellen, aufrufen, um den Wert zu generieren.
<?php
// generate a new token for the $_SESSION superglobal and put them in a hidden field
$newToken = generateFormToken('form1');
?>
Dann fügen Sie den Token als verstecktes Eingabefeld in das Formular selbst ein
<input name="token" type="hidden" value="<?php echo $newToken; ?>">
Nun sind wir bereit, die Token-Werte beim Absenden des Formulars miteinander zu vergleichen. Dazu erstellen wir eine Funktion.
function verifyFormToken($form) {
// check if a session is started and a token is transmitted, if not return an error
if (!isset($_SESSION[$form.'_token'])) {
return false;
}
// check if the form is sent with token in it
if (!isset($_POST['token'])) {
return false;
}
// compare the tokens against each other if they are still the same
if ($_SESSION[$form.'_token'] !== $_POST['token']) {
return false;
}
return true;
}
Diese Funktion prüft, ob der Token an beiden erforderlichen Stellen vorhanden ist und ob sie übereinstimmen. Wenn alle diese drei Bedingungen erfüllt sind, gibt die Funktion true zurück, andernfalls false. Jetzt prüfen wir diesen Wert, bevor wir fortfahren. Die Grundstruktur ist:
if (verifyFormToken('form1')) {
// ... more security testing
// if pass, send email
} else {
echo "Hack-Attempt detected. Got ya!.";
writeLog('Formtoken');
}
Hack-Protokollierung
Beachten Sie, dass wir in der obigen Struktur eine Funktion namens writeLog() verwenden, die einen String entgegennimmt. Es gibt eine Vielzahl von Umständen, unter denen wir böswillige Absichten erkannt und gestoppt haben. In diesen Fällen rufen wir die Funktion writeLog() auf, um den Fehler zu unserer eigenen Referenz zu protokollieren, und beenden dann das Skript.
Diese Funktion versucht, in eine Textdatei auf dem Server zu schreiben (diese Datei benötigt entsprechende Dateiberechtigungen, Schreibzugriff für den Benutzer) oder, falls dies fehlschlägt, sendet sie Ihnen eine E-Mail.
function writeLog($where) {
$ip = $_SERVER["REMOTE_ADDR"]; // Get the IP from superglobal
$host = gethostbyaddr($ip); // Try to locate the host of the attack
$date = date("d M Y");
// create a logging message with php heredoc syntax
$logging = <<<LOG
\n
<< Start of Message >>
There was a hacking attempt on your form. \n
Date of Attack: {$date}
IP-Adress: {$ip} \n
Host of Attacker: {$host}
Point of Attack: {$where}
<< End of Message >>
LOG;
// open log file
if($handle = fopen('hacklog.log', 'a')) {
fputs($handle, $logging); // write the Data to file
fclose($handle); // close the file
} else { // if first method is not working, for example because of wrong file permissions, email the data
$to = '[email protected]';
$subject = 'HACK ATTEMPT';
$header = 'From: [email protected]';
if (mail($to, $subject, $logging, $header)) {
echo "Sent notice to admin.";
}
}
}
Nichts POSTED, was wir nicht angefragt haben
Wenn Werte an uns übermittelt werden, die keine Namen von Eingabefeldern in unserem eigenen Formular haben, ist **definitiv** etwas Seltsames im Gange. Wir erstellen eine „Whitelist“ von akzeptablen POST-Namen und überprüfen dann jeden einzelnen.
// Building a whitelist array with keys which will send through the form, no others would be accepted later on
$whitelist = array('token','req-name','req-email','typeOfChange','urgency','URL-main','addURLS', 'curText', 'newText', 'save-stuff');
// Building an array with the $_POST-superglobal
foreach ($_POST as $key=>$item) {
// Check if the value $key (fieldname from $_POST) can be found in the whitelisting array, if not, die with a short message to the hacker
if (!in_array($key, $whitelist)) {
writeLog('Unknown form fields');
ie("Hack-Attempt detected. Please use only the fields in the form");
}
}
Gültige URL
Die clientseitige Validierung dieses Formulars überwacht dies, sodass es im Voraus abgefangen werden sollte, aber natürlich sollten wir auch im Backend prüfen.
// Lets check the URL whether it's a real URL or not. if not, stop the script
if (!filter_var($_POST['URL-main'],FILTER_VALIDATE_URL)) {
writeLog('URL Validation');
die('Please insert a valid URL');
}
Bereinigung von Werten
An diesem Punkt haben wir alle unsere Sicherheitsprüfungen durchgeführt und fahren mit der Erstellung und dem Versand der E-Mail fort. Die Übernahme aller Eingaben genau so, wie sie eingegeben wurden, und deren Weiterleitung ist ein potenzielles Sicherheitsrisiko. Zum Beispiel könnte JavaScript in ein Textfeld eingegeben und dann per E-Mail versendet und möglicherweise ausgeführt werden, wenn die E-Mail geöffnet wird.
Für Felder wie „Name“, bei denen es keinen Grund gibt, spezielle Tags zu verwenden, werden wir sie mit strip_tags() komplett entfernen. Für Textbereiche, in denen es Anlass zur Verwendung einiger Tags geben kann, werden wir nur die htmlentities()-Funktion verwenden, um sie sicher zu konvertieren.
Beispiel
$message .= "Name: " . strip_tags($_POST['req-name']) . "\n";
$message .= "NEW Content: " . htmlentities($_POST['newText']) . "\n";
Mehr und bessere Bereinigung
Krinkle schreibt dazu:
Ursprünglich hast du strip_tags() für normale Felder und
htmlentities()für Inhalte verwendet. Das ist in Ordnung, außer dass es bewährte Praxis ist, auch ENT_NOQUOTES und „UTF-8“ zu deklarieren, da sonst Zeichen wie der Akzent auf dem e („é“) zu Mist wie Å@ werden könnten. Und da die meisten Server automatisch Backslashes vor Eingaben hinzufügen, die über $_POST[] hereinkommen, ist es keine schlechte Sache, stripslashes vorsichtshalber auszuführen, sonst hättest du einen Backslash vor jedem einzelnen oder doppelten Anführungszeichen, das in das Formular eingegeben wurde, sobald es in der Mailbox ist.
function stripcleantohtml($s){
// Restores the added slashes (ie.: " I\'m John " for security in output, and escapes them in htmlentities(ie.: " etc.)
// Also strips any <html> tags it may encounter
// Use: Anything that shouldn't contain html (pretty much everything that is not a textarea)
return htmlentities(trim(strip_tags(stripslashes($s)), ENT_NOQUOTES, "UTF-8"));
}
function cleantohtml($s){
// Restores the added slashes (ie.: " I\'m John " for security in output, and escapes them in htmlentities(ie.: " etc.)
// It preserves any <html> tags in that they are encoded aswell (like <html>)
// As an extra security, if people would try to inject tags that would become tags after stripping away bad characters,
// we do still strip tags but only after htmlentities, so any genuine code examples will stay
// Use: For input fields that may contain html, like a textarea
return strip_tags(htmlentities(trim(stripslashes($s)), ENT_NOQUOTES, "UTF-8"));
}
Verwendung in diesem Beispiel
$message .= "Name: " . stripcleantohtml($_POST['req-name']) . "\n";
$message .= "NEW Content: " . cleantohtml($_POST['newText']) . "\n";
Warum nicht ein CAPTCHA verwenden?
CAPTCHAs tun ziemlich gute Arbeit, um Spam von Formularen fernzuhalten, aber wir machten uns hier mehr Sorgen um Hacking als um Spam. Außerdem, da dieses Formular für Leute ist, die wir wahrscheinlich MÖGEN und denen wir versuchEN zu HELFEN, werden wir sie nicht durch das nervige Hopsen durch einen CAPTCHA quälen. Wenn Sie jedoch interessiert sind, ist ein super-duper einfacher selbstgemachter Captcha, etwas wie „Was sind zehn minus fünf?“ in ein Textfeld zu fragen und dann nach den Werten „5“ und jeder Großbuchstabenkombination von „fünf“ zu suchen, und wenn es eine Übereinstimmung gibt, dann fortfahren, sonst nicht. Diese Version des Formulars hat bereits die Funktion writeLog(), die bereit zur Nutzung ist, und die Logik würde sich gut um die Zeilen 75 und 76 herum einfügen.
Wenn Sie einen etwas robusteren CAPTCHA wünschen, schauen Sie sich reCAPTCHA an, das ziemlich einfach zu bedienen ist, Menschen hilft und sehr zugänglich ist.
Sicherheits-Gurus?
Wenn wir hier über Sicherheit sprechen, gibt es tendenziell viele Meinungen darüber, wie die Dinge gemacht werden. Wenn Sie Ideen haben, teilen Sie sie bitte so konstruktiv wie möglich unten mit, und ich werde sie verdauen und sehen, wie wir uns im Laufe der Zeit verbessern können.
Guter Beitrag, und ziemlich wichtig für jeden Webdesigner, der irgendeine Art von Benutzereingaben erstellt.
Eine Sache: die Md5-Verschlüsselung... Das wird generell als „nicht wirklich sicher, besser SHA-256bit-Verschlüsselung verwenden“ bezeichnet. Aber wie macht man das? Es sollte eine sha256(string)-Funktion in PHP geben, aber ich kriege das nicht zum Laufen.
Erster Google-Treffer: http://www.nanolink.ca/pub/sha256/
Ja, das habe ich bemerkt. Aber ich möchte es in meinen eigenen PHP-Dateien verwenden, und es funktioniert nicht :-/ wie z. B. echo sha256(‘hallo’); gibt hier nichts aus. Ich habe viel gegoogelt, keine Sorge. Ich habe eigentlich auf Antworten wie „Oh, er hat vergessen, zu..“ gehofft, weil ich denke, dass es etwas Einfaches ist, an das ich nicht gedacht habe. Aber trotzdem danke! :-)
Ich glaube, das ist es, wonach Sie suchen.
Der (Anti-CSRF-)Token wird in einer Session gespeichert. Und eine Session wird nur eine halbe Stunde lang gespeichert. Innerhalb dieser halben Stunde können Sie keine MD5-Kollision erhalten.
Und MD5 ist keine Verschlüsselung, es ist ein Hash, daher kann er nicht entschlüsselt werden. :)
Der Token wird verwendet, um den Benutzer vor CSRF-Angriffen zu schützen. Es ist nur ein zufälliger String, der mit den Formulardaten als eine Art ID gesendet wird, die andere nicht haben. Ohne den richtigen Token/die richtige ID wird das Formular nicht verarbeitet.
Aber er kann nachgeschlagen werden. Denken Sie an einen Wörterbuchangriff.
Aber nur das Senden einer POST-Anfrage an das Formular funktioniert nicht, da Sie zuerst einen Token benötigen. Um diesen Token zu erhalten, müssen Sie die Website besuchen (GET-Anfrage).
Daher funktionieren das Senden von POSTs in Form eines Wörterbuchangriffs nicht.
Oh ja. Es gibt diese Website, die eine Datenbank mit den Werten und ihren Hashes enthält, kombiniert mit insgesamt etwa 1,2 Milliarden Einträgen. Das ist krank.
Ausgezeichneter Beitrag – jeder Webmaster sollte diese Schritte durcharbeiten, bevor er sich mit Captcha-Lösungen befasst.
Abgesehen davon, dass eine bessere Benutzererfahrung geboten wird, gibt es oft einen spürbaren geschäftlichen Vorteil – wir haben kürzlich reCAPTCHA von unserem Registrierungsformular entfernt und einige dieser Techniken verwendet. Dies führte zu einem zweistelligen Anstieg der Anzahl der von uns erzielten Konversionen.
Das war eine großartige Idee. Ich mag es. Hashes sind großartig.
Ich habe eine Frage, die etwas vom Thema abweicht. Warum verwenden viele Webdesigner auf ihren Websites, die ich in letzter Zeit besucht habe, nicht target=”_blank” in ihren Anker-Tags? Es hält externe Websites von Ihren eigenen getrennt und verursacht weniger Verwirrung für allgemeine „Surfer“.
Gut gemacht, ich habe das wirklich gerne gelesen. Die meisten Websites sind überhaupt nicht gesichert, aber das hier rückt alles an die richtige Stelle. Vergessen Sie auch nicht Dinge wie HTTPS und das Salzen von Dingen.
Machen Sie weiter so!
Sie verwenden die hash()-Funktion.
Siehe hier
Beispiel
hash(“sha256”, “Mein zu hashender String”);
Wir haben die CAPTCHA-Validierung entfernt und uns für Wufoo entschieden, um Formulare bereitzustellen, und sahen einen riesigen Anstieg der eingereichten Formulare (wie verdoppelt). Das ist großartig, da mein Chef die monatlichen Kosten hinterfragt und nach Alternativen gefragt hat.
Guter Beitrag! Ich denke, das Token-Ding ist großartig. Es ist nicht nur nützlich, um sicherzustellen, dass ein Formular von der Seite, die es generiert hat, übermittelt wird, sondern es ist auch gut, es mit AJAX-Anfragen zu verwenden, um sicherzustellen, dass die Anfrage von der beabsichtigten Seite durchgeführt wurde.
Tolle Ausarbeitung, Chris. Immer auf der Suche nach Workarounds für CAPTCHA. Sie sind ein Angriff auf den Konversionsprozess und eine Beleidigung der Benutzerfreundlichkeit.
Ich konnte SQL in eines der Textfelder einfügen.
Das Formular sendet eine E-Mail und Sie haben SQL injiziert? Gute Arbeit, Kumpel!
Werden Sie posten, was Sie eingegeben haben und in welches Feld? Ich möchte auch auf meinen eigenen Formularen auf solide SQL-Injection-Versuche testen.
Es gibt keine SQL-Injection in einer PHP-Datei, die keine Datenbank berührt.
Was Sie hier getan haben, ist eine ziemlich gute Gegenmaßnahme, aber beachten Sie, dass es heimtückische Wege gibt, JavaScript ohne Tags (oder was wir normalerweise als Tags bezeichnen) einzuschleusen.
Irgendwann ist es immer möglich, zu hacken. Die Idee ist, es so schwer zu machen, dass sich niemand die Mühe macht.
Löschen Sie den Token nach einer erfolgreichen Übermittlung, um zu verhindern, dass Leute bei F5 „zurückspringen“ und dasselbe Formular immer wieder erneut übermitteln.
Ich verwende reCAPTCHA auf einer Website und habe ziemlich gute Erfolge. Vielleicht versuche ich das, wenn ich Zeit finde…
„Dies stellt sicher, dass jede Übermittlung des Formulars unser Formular ist und kein Skript von Drittanbietern, das von einem anderen Server aus auf uns einstürmt.“
Warum nicht PHP's $_SERVER[‘HTTP_REFERER’] verwenden, um zu sehen, ob die Anfrage von Ihrer Formularseite kam?
Weil er vom Client gefälscht werden kann.
Weil das Referer-Feld leicht manipuliert werden kann. Der Client kann jeden Wert senden, den der Benutzer möchte. Mein Opera sendet zum Beispiel überhaupt keine Referer-Informationen.
Eine zusätzliche Validierung von HTTP_REFERER würde nicht schaden, also machen Sie es, wenn jemand darüber nachdenkt. Es ist ja nicht so, dass alle Spammer schlau sind *räusper*
interessanter Beitrag, den Sie hier haben. Ich werde es bald überprüfen.
in der Tat, ein interessanter Beitrag.
Tolles Thema, Chris! Bei Wufoo-Ausfällen wie gerade jetzt ist es Zeit, selbst Formulare zu programmieren.
Das wird nützlich sein!
NIEMALS, jemals, jemals, jemals, jemals, jemals, jemals, jemals, niemals MD5 als Ihren bevorzugten Algorithmus verwenden! Niemals! …außer ohne Kondom.
SHA1 ist viel sicherer als MD5, aber beide können durch Brute-Force geknackt werden, MD5 viel einfacher als SHA1.
Obwohl Sie bei allen Hashes einen SALT (das Kondom, von dem ich gesprochen habe) verwenden sollten. Dies kann sowohl MD5 als auch SHA1 sicherer machen. Anstatt 200.000 Versuche mit MD5 oder fast eine Million Versuche mit SHA1 zu benötigen, wären etwa 800 Billionen Versuche erforderlich, um ein SHA1 + vorangestelltes SALT korrekt zu erraten.
Daher, wenn Sie etwas herumspielen wollen, tragen Sie ein Salt-Kondom.
wäre das eine noch bessere Lösung?
irgendwelche Gedanken dazu?
$salt = time();
$string = uniqid(microtime(), true);
switch( substr( $salt, -1, 1) ) {
case 1
$token = sha1( $salt . $string ) . substr( $salt , 1, 3);
break;
case 2
$token = sha1( $string . $salt ) . substr( $salt , 3, 2);
break;
case 3
$token = substr( $salt , 5, 2) . sha1( $salt . $string ) ;
break;
}
Besser oder nicht?
Viel besser, aber ich habe auch das im SHA1 PHP Manual gefunden (keine Anerkennung für mich, ich habe mir das nicht ausgedacht), das auch gut darin zu sein scheint, ein schwierigeres Pseudo-Salt zu erstellen.
<?php
function createHash($inText, $saltHash=NULL, $mode='sha1'){
// hash den Text //
$textHash = hash($mode, $inText);
// Setzen, wo das Salt im Hash erscheinen soll //
$saltStart = strlen($inText);
// Wenn kein Salt gegeben ist, erstelle einen zufälligen //
if($saltHash == NULL) {
$saltHash = hash($mode, uniqid(rand(), true));
}
// Füge das Salt an der Position der Passlänge in den Text-Hash ein und hashe es //
if($saltStart > 0 && $saltStart < strlen($saltHash)) {
$textHashStart = substr($textHash,0,$saltStart);
$textHashEnd = substr($textHash,$saltStart,strlen($saltHash));
$outHash = hash($mode, $textHashEnd.$saltHash.$textHashStart);
} elseif($saltStart > (strlen($saltHash)-1)) {
$outHash = hash($mode, $textHash.$saltHash);
} else {
$outHash = hash($mode, $saltHash.$textHash);
}
// Setze das Salt an den Anfang des Hash //
$output = $saltHash.$outHash;
return $output;
}
?>
Da rand() die Zeit verwendet, um seine pseudo-zufällige Summe zu erstellen, denke ich, dass dies auch eine gute Methode wäre, um ein Salt zu erstellen.
Um Hacking noch mehr zu bekämpfen, versuchen Sie, ein Formular-Timeout zu verwenden.
Ich habe darüber in einem Artikel geschrieben: serversidemagazine.com/php/php-security-measures-against-csrf-attacks
Außerdem haben in den Kommentaren dieses Artikels einige Leser mit der Idee von AJAX-CSRF-Angriffen experimentiert, was eine ziemlich neue Hacking-Methode ist.
Das war eine interessante Lektüre und eine großartige Themenwahl. Der Token und die Whitelist sind interessante Ideen. Ich werde diese Techniken bei der nächsten Formularerstellung auf jeden Fall in Betracht ziehen.
Danke Chris!
Genial!
Hallo, ich dachte, ich weise darauf hin, dass im ValidURL-Checker, wenn ich eingab
http://www.somesite.com
Es wurde eine ungültige URL zurückgegeben, aber wenn ich http:// hinzufügte, wurde true zurückgegeben.
Ich sehe mögliche Fehler in dieser Routine, nämlich dass Clients wahrscheinlich nicht http:// eingeben werden, weil sie einen Website-Link in seinem einfachsten Format „www.sitename.com“ sehen.
In Anwendungen, die ich schreibe, prüfe ich, ob der String http:// enthält – wenn ja, lasse ich den String unverändert. Wenn kein http:// gefunden wird, füge ich es mit der String-Funktion str_replace hinzu.
Ich kann mich irren, aber ich bin ein junger Webentwickler (20) und mache das erst seit einem Jahr, aber es scheint logisch.
sieht in Firefox großartig aus. im guten alten IE 7 & 8 wird das Dropdown verdeckt…
frag mich, ob ein z-index-Snafoo das Problem lösen könnte…?
Die meisten dieser Kommentare sind Unsinn. Diese Methode ist gut für CSRF, aber nichts hindert jemanden daran, ein Skript remote auszuführen, die Schlüssel-Werte aus dem Formular abzurufen und es remote zu übermitteln.
Diese exakt gleiche Methode wird seit Jahren in Open-Source-Systemen verwendet. Sie ist nichts Neues.
Ich stimme Danny zu – die Verwendung von MD5 ist in diesem CRSF-Beispiel kein Problem.
Zum Beispiel verwendet Djangos CRSF-Middleware MD5
http://code.djangoproject.com/browser/django/trunk/django/contrib/csrf/middleware.py#L27
Es gibt keine Sicherheitslücke in dieser Implementierung.
Im Allgemeinen bestätigen diese Kommentare das Offensichtliche – versuchen Sie nicht, CSRF selbst zu implementieren – Sie werden es falsch machen. Verwenden Sie stattdessen eine bekannte/unterstützte Bibliothek. Django verwendet die CRSF-Middleware – andere Sprachen und Frameworks haben zweifellos ihre eigenen Implementierungen.
Sehr informativer Artikel. Nebenbei bemerkt, auf Ihrem Formular
Zusätzliche URL's / Bereiche
Sollte sein
Zusätzliche URLs / Bereiche
Kein Apostroph. :)
Hallo Chris,
Leute reden hier offensichtlich viel über Entwicklung – ich denke über die Benutzerfreundlichkeit des Formulars nach. Es gibt bestimmte Dinge, die ich vermisse oder als Einschränkung sehe
1) Eine E-Mail zu senden ist für den Kunden schneller, als ein Formular auszufüllen/zu senden.
2) Einige Kunden bereiten Änderungen in Dokumenten vor (PDF, Word). Warum sollten sie ein Formular verwenden?
2) Formulare können keine komplexen Änderungen bearbeiten (mehrere Änderungen auf mehreren Seiten, mehrere zusammenhängende Änderungen, Designänderungen, ...)
3) Formulare können keine Mediendateien (Dokumente, Bilder) hochladen und senden
nur um ein paar zu nennen. Ich denke, dass die meisten Kunden ein Formular nicht für Änderungen verwenden werden.
Prost
Hallo Chris,
Schönes Tutorial zur Formularsicherheit, dient dies als Alternative zu Captcha und kann es auch Bots blockieren?
Ciao
Hallo,
Eine weitere Frage: Schützt diese Methode Formulare vor xrumer?
Danke
Warum sendet dieses Formular nicht? Ich habe die entsprechenden E-Mails geändert?
CSRF-Schutz ist jedoch nicht narrensicher – es reicht ein GET-Aufruf an die Formularseite, das Auslesen des Tokens und dessen Übertragung zusammen mit den Sitzungsinformationen in die POST-Anfrage, um dies zu umgehen. Da es Spam-Bots gibt, die Formulare ausfüllen und absenden (anstatt sie nur abzusenden), muss dieser Ansatz mit einem weiteren kombiniert werden.
Ich habe die Demo-Datei heruntergeladen. Danke fürs Teilen. Aber etwas scheint am Ende des PHP-Teils unvollständig zu sein, direkt nach der mail()-Funktion, kurz vor Beginn des HTML. Da ist eine „if“-Klausel ohne Body. Ich weiß nicht, wie dieser Blog Code behandelt, aber ich versuche es
} else {
if (!isset($_SESSION[$form.’_token’])) {
// Sollte hier nicht etwas stehen?
} else {
echo “Hack-Versuch erkannt. Erwischt!.”;
writeLog(‘Formtoken’);
}
wow
das ist seltsam. Ich habe einen Beitrag geschrieben und er ist 4 Posts über dem letzten erschienen. Das habe ich noch nie gesehen. Jedenfalls… 4 Posts weiter oben gibt es eine Frage nach einer leeren „if“-Bedingung in der Demo-Datei. Kann mir jemand helfen, herauszufinden, warum sie da ist und was ihr fehlen könnte? Danke!
Ach, vergiss es. Seltsam. Meine Beiträge vom 2. Juli erscheinen vor denen vom 19. und 20. Mai.
Nur ein Gedanke, aber wahrscheinlich ist es besser, den Namen des Eingabefeldes als Token zu verwenden. So ist der Name des Eingabefeldes anders, falls jemand versucht, das Token mit einer GET-Anfrage zu erhalten. Könnte aber sowieso ein wenig besser sein.
Auch, md5 sha1, was auch immer. Ich glaube nicht, dass es überhaupt eine Rolle spielen sollte. Hier werden keine Informationen verschlüsselt, also keine Sorge. Sie überprüfen nur, ob es dasselbe ist. Alles, was wirklich zählen sollte, ist, dass das Token ziemlich einzigartig ist und für jede Anfrage als dasselbe verifiziert werden kann.
Ein Hacker kann den Token-Wert mit regulären Ausdrücken leicht aus dem Eingabefeld erhalten.
z.B.: Öffnen Sie unsere Login-Seite mit Ajax oder Curl und erhalten Sie den Token-Wert aus dem versteckten Eingabefeld mit regulären Ausdrücken.
Wie kann man das verhindern?
Hallo, für all diejenigen, die sich fragen, wie man einen Hacker davon abhält, das Token zu erhalten, können Sie Folgendes verwenden:
Danke, das speichert den Cookie als Whirlpool und macht es sicher und http-only (keine Ajax-Anfragen).
Ich bin kein Experte, aber wenn es hilft, weiß ich es nicht.