Токены XSRF безопасны только как канал, по которому отправляется страница. Используйте https
и только https
в этой форме и отправляйте ее только на конечную точку https
. В противном случае MITM может получить ваш токен XSRF из формы в том виде, в котором он был обслужен или отправлен.
while ($row = mysql_fetch_array($getregisterkey))
{
$registerkey = mysql_real_escape_string($row['key']);
};
никогда не будет выполняться при нулевых строках, и в этом случае вы не получаете большой энтропии от $getregisterkey
, когда позже делаете
$_SESSION['register_token']=sha1(uniqid(rand(), TRUE).$registerkey);
поэтому я бы позаботился о том, чтобы ваша реализация работала быстро, если возвращено ноль строк. Возможно, измените значение на if ($row = mysql_fetch_array(...)) { ... } else { /* abort */ }
, поскольку дополнительные строки не приносят пользы.
rand()
должен быть либо действительно случайным, либо криптографически стойким PRNG.
Я не знаком со стандартными библиотеками PHP, но [wikipedia] предполагает, что rand()
не является криптографически сильным. Википедия говорит
Есть предложения по добавлению генерации случайных чисел в PHP.
Сильная криптография в PHP предлагает использовать openssl_random_pseudo_bytes()
Не используйте rand () или mt_rand ()
Чтобы сгенерировать криптографически сильное случайное число в PHP, вы должны использовать функцию openssl_random_pseudo_bytes()
библиотеки OpenSSL.
Если вы используете слабую случайность, то злоумышленник может наблюдать за сгенерированными вами числами (запрашивая несколько версий формы и анализируя скрытый ввод) и использовать это, чтобы выяснить, какими могут быть следующие числа, и подделать токены CSRF.
Если злоумышленник изменит свойство сеанса 'register_token_time'
, он сможет избежать проверок XSRF.
Например, если у вас есть страница, которая делает
$_SESSION[$_POST['x']] = $_POST['y'];
тогда злоумышленник может POST
x=register_token&y=pwnd
, чтобы заменить register_token, хранящийся в сеансе, а затем отправить сообщение с
token=pwnd
и обойдите защиту XSRF.