Это нормально для одиночного запроса, если злоумышленник наблюдает только за временем ответа.
Однако, если злоумышленник сделает достаточно запросов, эта случайная задержка может усредниться, как указано в ответе Скотта со ссылкой на сообщение в блоге ircmaxell:
Таким образом, если нам нужно было запустить 49 000 тестов, чтобы получить точность 15 нс [без случайной задержки], то нам потребовалось бы, возможно, 100 000 или 1 000 000 тестов той же точности со случайной задержкой. Или, возможно, 100000000. Но данные все еще есть.
В качестве примера давайте оценим количество запросов, которые потребуются для временной атаки, чтобы получить действительный 160-битный идентификатор сеанса, например PHP с 6 битами на символ. что дает длину 27 символов. Предположим, как в связанном ответе, что атака может быть выполнена только на одного пользователя одновременно (поскольку они сохраняют пользователя в поиск в куки).
В лучшем случае из сообщения в блоге, 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 не является криптографически безопасный:
Внимание! Эта функция не генерирует криптографически безопасные значения и не должна использоваться в криптографических целях. Если вам нужно криптографически безопасное значение, рассмотрите возможность использования _5 _ вместо этого.
Это означает, что теоретически злоумышленник может предсказать, что rand
собирался сгенерировать, а затем использовать эту информацию, чтобы определить, была ли задержка времени ответа от вашего приложения результатом случайного сна или нет.
Лучший способ приблизиться к безопасности - это предположить, что злоумышленник знает ваш исходный код - единственное, что является секретом от злоумышленника, - это такие вещи, как ключи и пароли - предполагайте, что он знает используемые алгоритмы и функции. Если вы все еще можете сказать, что ваша система защищена, даже если злоумышленник точно знает, как она работает, вы будете почти всегда там. Такие функции, как rand
, обычно устанавливаются для заполнения с текущим временем дня, поэтому злоумышленник может просто убедиться, что его системные часы установлены так же, как и на вашем сервере, а затем сделать запросы, чтобы убедиться, что их генератор соответствует вашему.
По этой причине лучше избегать небезопасных случайных функций, таких как rand
, и изменить свою реализацию на использование openssl_random_pseudo_bytes
, что будет непредсказуемо.
Кроме того, согласно комментарию ircmaxell, sleep
недостаточно детализирован, поскольку он принимает только целое число для представления количества секунд. Если вы собираетесь попробовать этот подход, просмотрите time_nanosleep
со случайным количество наносекунд.
Эти указатели должны помочь защитить вашу реализацию от такого типа временных атак.
person
SilverlightFox
schedule
09.02.2015
hash_equals()
и закончите. - person Scott Arciszewski   schedule 13.02.2015