Ich weiß, es gibt zwei Hauptlösungen gegen CSRF-Angriffe.Schutz vor CSRF-Angriffen in PHP für mehrere Browser-Registerkarten
- ein Token pro Sitzung
- Token für alle einzigartigen Formen
wählte ich die zweite, aber es ist ein Problem. Wenn der Besucher ein Formular in zwei Registerkarten öffnet, überschreibt das Formular-Token auf der zweiten Registerkarte die vorherigen Token. Ich habe einen Code geschrieben, um dieses Problem zu lösen. Meine Frage ist: Ist es eine gute Lösung, oder muss ich daran arbeiten? (Es gibt nur die wichtigsten Teile in den Beispielen.)
##### CONFIG & FUNCTION.PHP #####
// INITIALIZING - RUN ONLY ONCE
$_SESSION["csrf_tokens"]["postcomment"] = array();
$_SESSION["csrf_tokens"]["postcommentedit"] = array();
// etc, etc.
function makearandomtoken()
{
// a simple but secure way
return bin2hex (openssl_random_pseudo_bytes (32));
}
##### POSTCOMMENT_FORM.PHP #####
// new form for comment under a post, so create a new token
$created_token = makearandomtoken();
array_push ($_SESSION["csrf_tokens"]["postcomment"], $created_token);
// the form (only with important parts)
print "<form>\n";
print "<input type=\"hidden\" name=\"token\" value=\"$created_token\">\n";
print "</form>\n";
##### POSTCOMMENT_EXECUTE.PHP #####
// get the token from POST variable
$received_token = filter_input (INPUT_POST, 'token', FILTER_UNSAFE_RAW);
// check it
if (in_array($received_token, $_SESSION["csrf_tokens"]["postcomment"]))
{
// VALID token, disable it
$token_index = array_search($received_token, $_SESSION["csrf_tokens"]["postcomment"]);
unset ($_SESSION["csrf_tokens"]["postcomment"][$token_index]);
}
else
{
// INVALID token -> CSRF attempt
die(); // or do anything
}
Wenn für Ihre App 2 Tabs erforderlich sind, führen Sie ein einzelnes CSRF-Token pro Anmeldung aus. Wenn dies nicht der Fall ist, sollte der Benutzer nicht mehrere Tabs öffnen. Setzen Sie auch nur Tokens, wenn Sie ein Formular auf diese Weise präsentieren. Sie könnten mehrere Registerkarten für nicht formularbasierte Seiten haben. –
Sieht gut aus. Das einzige, was fehlt, ist eine Strategie, um alte unbenutzte Token zu löschen und/oder ein Limit für die Anzahl gültiger Tokens pro Benutzer. – jh1711
Sie müssen die Anzahl der Token begrenzen, sonst könnte ein Angreifer diese verwenden, um die Sitzung zu füllen. Und da die Sitzungsgröße nur durch das PHP-Skript-Speicherlimit begrenzt ist, könnte es bei mehreren Konten den Server drosseln. – Jarzon