Краткий, но интересный здесь. Возможно, у меня здесь есть что-то странное, но я потерял несколько часов и не могу понять, в чем проблема.
У меня есть функция, которая производит одноразовый номер, например, так. На данный момент это не очень сложно, но это скорее эксперимент с новой для меня концепцией. Я использую random_bytes в качестве естественного преемника mcrypt_create_iv
для PHP7 +:
$token = random_bytes(16);
это тогда сохранено как так:
$session->add('nonce',$token);
(which is essentially....)
$_SESSION[$var] = $val;
будучи одновременно использованным в моей форме, вот так:
<input name="token" type="hidden" value="<?=$token?>">
Форма отправляется и проходит некоторую проверку и так далее. В рамках этого я получаю оба значения:
$token = $_POST['token'];
$nonce = $session->get('nonce');
и тогда у меня есть точка проверки для дальнейшего выполнения — продолжить, только если два значения совпадают. Проблема в том, что я не могу заставить их проверить. Ни один из этих токовых выходных данных не соответствует действительности:
if(hash_equals($nonce, $token))
if($nonce === $token)
var_dump
показывает, что обе строки одинаковой длины, но по какой-то причине они не сопоставимы. Оба значения выглядят так, как будто они совпадают.
if(hash_equals($nonce, $nonce))
равно true (как и следовало ожидать), поэтому я могу только предположить, что одно из значений изменяется по пути, либо $_POST
или через мою поисковую функцию (которая буквально просто читает из сеанса).
Я был бы признателен за любую помощь / предложения с этим — я либо пропускаю что-то очевидное, либо слишком неопытен с этим.
Не все случайные байтовые значения действительны непосредственно в HTML. Если строка содержит значения вне регулярной последовательности букв и цифр ascii ([0-9a-zA-z]
), все может случиться, если вы не избежите этого для контекста HTML. Ты можешь использовать htmlspecialchars
чтобы при необходимости экранировать значения, или использовать вместо этого версию случайных байтов в кодировке хэша или base64.
Хорошим примером будет, если значение ASCII "
содержится в 16 случайных байтов, ваш HTML-атрибут заканчивается рано. HTML не очень любит управляющие последовательности (младшие символы ascii) или буквы вне текущей кодировки (если UTF-8, любое значение выше 127 должно быть допустимой кодовой точкой UTF-8 при просмотре через несколько байтов).
Других решений пока нет …