Gumbo
Erfahrenes Mitglied
Folgendes ist möglich (hab’ ich auch schon in verwandten Themen genannt):
Dadurch ist allerdings immer nur ein Formular gültig. Wenn mehrere Formular gleichzeitig geöffnet sind, ist immer nur das zuletzt aufgerufene gültig, da der Zufallsschlüssel die vorherigen überschreibt.
Dies kann aber dadurch verhindert werden, dass mehrere Schlüssel gespeichert werden. Dabei können auch noch weitere Werte zur Prüfung gepseichert werden, etwa:
Am besten sollten auch nicht veränderbare Argument wie etwa IDs serverseitig in der Token-Variable gespeichert werden (hier durch das „args“-Array angedeutet), damit sie für den Benutzer unsichtbar und damit auch nicht veränderbar sind.
PHP:
$_SESSION['token'] = md5(uniqid(rand(), true));
echo '<input type="hidden" name="token" value="'.$_SESSION['token'].'">';
PHP:
if( empty($_POST['token']) || empty($_SESSION['token']) || $_POST['token'] !== $_SESSION['token'] ) {
echo 'Ungültige Aktion!';
}
unset($_SESSION['token']);
Dies kann aber dadurch verhindert werden, dass mehrere Schlüssel gespeichert werden. Dabei können auch noch weitere Werte zur Prüfung gepseichert werden, etwa:
PHP:
$maxValidTokens = 5; // Anzahl der gleichzeitig gültigen Schlüssel
$relPath = './agb_edit.php'; // relativer Pfad zum verarbeitenden Skript
$absPath = substr(realpath($relPath), strlen($_SERVER['DOCUMENT_ROOT'])); // absoluter Pfad zum verarbeitenden Skript
do {
$token = md5(uniqid(rand(), true));
} while( isset($_SESSION['tokens'][$token]) );
$_SESSION['tokens'][$token] = array(
'href' => $absPath,
'time' => time(),
'args' => array(
'foo' => 'bar',
),
);
if( count($_SESSION['tokens']) > $maxValidTokens ) {
array_shift($_SESSION['tokens']);
}
echo '<input type="hidden" name="token" value="'.$token.'">';
PHP:
$tokenMaxLifetime = 300; // fünf Minuten Gültigkeit
$validToken = true;
if( !isset($_POST['token']) || !isset($_SESSION['tokens'][$_POST['token']]) || $_SESSION['tokens'][$_POST['token']]['href'] != $_SERVER['REQUEST_URI'] ) {
$validToken = false;
echo 'Invalid Token';
} else if( time() - $_SESSION['tokens'][$_POST['token']]['time'] > $tokenMaxLifetime ) {
$validToken = false;
echo 'Token expired';
} else {
foreach( $_SESSION['tokens'][$_POST['token']] as $key => $value ) {
$_POST[$key] = $value;
}
}
unset($_SESSION['tokens'][$_POST['token']]);
if( $validToken === true ) {
// Verarbeitung der Daten
}