Это нормально для по одному запросу, если единственным наблюдаемым атакующим боковым каналом является время отклика.
Однако, если злоумышленник делает достаточно запросов эта случайная задержка может усреднить, как указано в @Scott's answer со ссылкой ircmaxell's blog post:
Так что, если нам нужно запустить 49,000 тесты, чтобы получить точность 15ns [без случайной задержки ], тогда нам понадобится, возможно, 100 000 или 1 000 000 тестов с одинаковой точностью со случайной задержкой. Или, может быть, 100 000 000. Но данные все еще существуют.
В качестве примера давайте оценим количество запросов, которые должны иметь временную атаку, чтобы получить действительный 160-битный идентификатор сеанса, такой как PHP at 6 bits per character which gives a length of 27 characters. Предположим, что, как и linked answer, атака может выполняться только на одного пользователя одновременно (поскольку они хранят пользователя для поиска в файле cookie).
Принимая наилучший случай из сообщения в блоге, 100 000, количество перестановок будет 100,000 * 2^6 * 27
.
В среднем, злоумышленник найдет значение на полпути через количество перестановок.
Это дает количество запросов, необходимых для обнаружения идентификатора сеанса от временной атаки до 86 400 000. Это сравнивается с 42 336 000 запросов без вашей предлагаемой защиты времени (при условии, что точность в 15 нс, как и в блоге).
В блоге, взяв самую длинную тестированную длину, 14, в среднем составляло 0,01171 секунды, что означает, что 86 400 000 займет 1,011,744 секунды, что соответствует 11 дням 17 часов 2 минуты 24 секунды.
Может ли случайный сон предотвратить временные атаки?
Это зависит от контекста, в котором используется ваш случайный сон, и силы бита строки, которую она защищает.Если функция «сохранить меня вошла в систему», которая является контекстом в связанном вопросе, может стоить злоумышленнику потратить 11 дней на использование тактовой атаки для грубой силы. Тем не менее, это предполагает идеальные условия (т. Е. Довольно последовательное время отклика из вашего приложения для каждой проверенной позиции строки и без сброса или опрокидывания идентификаторов). Кроме того, этот вид активности от злоумышленника создаст много шума, и, скорее всего, они будут обнаружены через IDS и IPS.
Он не может полностью предотвратить их, но это может сделать их более трудными для исполнения злоумышленником. Было бы намного проще и лучше использовать что-то вроде hash-equals
, которое предотвратило бы временные атаки, полностью предполагая, что длины строк равны.
Ваш предложенный код
function timingSafeCompare($a,$b) {
sleep(rand(0,100));
if ($a === $b) {
return true;
} else {
return false;
}
}
Обратите внимание, что rand
функция PHP не криптографически безопасный:
Внимание Эта функция не создает криптографически безопасных значений, и не должны использоваться для криптографические цели. Если вам требуется криптографически безопасное значение, попробуйте вместо этого использовать openssl_random_pseudo_bytes()
.
Это означает, что в теории злоумышленник может предсказать, что rand
собирается генерировать и использовать эту информацию, чтобы определить, была ли ответ время задержки из вашего приложения из-за случайный сон или нет.
Лучший способ приблизиться к безопасности - предположить, что злоумышленник знает ваш исходный код - единственное, что секрет от злоумышленника должно быть таким, как ключи и пароли, - предположить, что они знают используемые алгоритмы и функции. Если вы все еще можете сказать, что ваша система защищена, даже если злоумышленник точно знает, как это работает, вы будете в основном там. Такие функции, как rand
, обычно устанавливаются на семя с текущим временем суток, поэтому злоумышленник может просто удостовериться, что их системные часы установлены так же, как ваш сервер, а затем делают запросы на подтверждение того, что их генератор соответствует вашим.
В связи с этим, лучше избегать небезопасных случайных функций, таких как rand
и изменить свою реализацию, чтобы использовать openssl_random_pseudo_bytes
, что будет непредсказуемо.
Кроме того, согласно комментарию ircmaxell, sleep
не является достаточно узким, поскольку он принимает только целое число, представляющее количество секунд. Если вы попытаетесь использовать этот подход, посмотрите на time_nanosleep
со случайным числом наносекунд.
Эти указатели должны помочь защитить вашу реализацию от такого типа атаки времени.
Просто используйте 'hash_equals()' и назовите это днем. –