Использование временных меток для предотвращения перехвата сеанса?

Я искал способы защиты от перехвата сеансов, когда кто-то крал cookie-файл сеанса и использовал его для получения доступа к системе.

Такие программы, как http://codebutler.com/firesheep позволяют легко прослушивать сеансы в открытых беспроводных сетях, а другие способы получения сеансов включают атаки с использованием межсайтовых сценариев или просто физическое снятие их с компьютера жертвы.

Использование SSL для защиты всех сеансов связи cookie-файлов с сервером имеет решающее значение для предотвращения перехвата Firesheep, а настройка HTTPOnly для cookie-файлов помогает предотвратить возможность чтения cookie сеансовых cookie-файлов при атаках XSS, но все же уязвима для атак на основе AJAX.

Другим уровнем является включение токена безопасности или одноразового номера в файл cookie сеанса, который обновляется при каждом запросе. Вы сохраняете токен в хранилище данных на стороне сервера и в файле cookie, и при каждом запросе вы сравниваете, что токен в файле cookie совпадает с токеном в хранилище данных.

Если токены не совпадают, это может указывать на то, что кто-то украл сеанс и пытается его использовать, чтобы вы могли либо проигнорировать запрос, либо аннулировать сеанс и потребовать от пользователя повторной аутентификации. Однако несоответствующие токены также могут быть результатом медленного / нестабильного соединения.

Например, может иметь место случай, когда сервер получает запрос от реального пользователя, обновляет токен сеанса в хранилище данных сервера и отвечает пользователю сессионным куки-файлом, который содержит обновленный токен. Но пользователь не получает ответ из-за медленного / нестабильного соединения, поэтому у пользователя все еще есть старый токен сеанса, в то время как новый хранится на сервере. Когда пользователь повторяет запрос, токены не совпадают.

Один из способов смягчить эту проблему - позволить серверу сохранить историю последних нескольких токенов и проверить, совпадают ли они, но затем возникает ситуация, сколько токенов нужно сохранить, и в зависимости от того, насколько нестабильно соединение или насколько пользователь доволен кликом, сервер может перебирать историю до того, как соединение восстанавливается, а сессия пользователя обновляется браузером.

Альтернативой хранению истории токенов является отметка времени каждого сеанса и проверка, находятся ли отметки времени в некотором коротком заданном диапазоне, скажем, 30 секунд. Если временная метка cookie сеанса пользователя находится в пределах 30 секунд от сохраненной временной метки сеанса сервера, то сеанс считается подлинным.

Пример псевдокода

def authenticate_request():

    if (stored_session.timestamp - session.timestamp > 30 seconds):
        return False
    return True

Это позволяет избежать необходимости сохранять историю токенов - метка времени становится токеном - но у злоумышленников есть 30-секундное окно для возможности перехватить сеанс после его кражи. Хотя это и так, альтернатива истории токенов не лучше, потому что она дает злоумышленникам потенциально более длительное окно возможностей.

Другие подходы к проверке IP-адресов и изменений User-Agent также имеют проблемы. Пользовательские агенты легко подделываются, и если злоумышленник может получить сеанс пользователя, он может легко определить пользовательский агент с помощью того же кода XSS или с помощью других средств.

Если пользователь подключен к мобильному устройству, его IP-адрес может часто меняться, что приведет к множеству ложных срабатываний. Кроме того, злоумышленник может находиться за брандмауэром одной компании, поэтому IP-адрес пользователя и злоумышленника совпадают с внешним веб-сервером.

Является ли использование метки времени правильным подходом или есть лучший способ? Правильный ли 30-секундный буфер? Какие крайние случаи я пропускаю?

1 ответ

Я не вижу, как будет работать отметка времени. Это потребовало бы от пользователя никогда не тратить больше 30 секунд на страницу перед отправкой другого запроса на сервер. Я уверен, что потратил намного больше 30 секунд, читая эту страницу и набирая этот ответ, прежде чем нажать "Опубликовать".

Мне кажется, что существует внутренняя проблема, заключающаяся в том, что любые данные, которые вы отправляете по линии, могут быть перехвачены и дублированы. Шифрование пароля не решает проблему, потому что хакер может перехватить зашифрованное значение и затем отправить это зашифрованное значение. Его не волнует, что такое незашифрованное значение.

Та же история для любого токена, который вы отправляете. Хакер может перехватить токен и скопировать его.

Единственная идея, о которой я слышал, которая, кажется, решает проблему, - это система вызова и ответа, использующая открытый и закрытый ключи: A создает произвольную строку символов, шифрует ее с использованием открытого ключа B и отправляет ее B. B расшифровывает, что строка, используя свой закрытый ключ и отправляет расшифрованное значение обратно вместе с данными своего приложения. Затем A проверяет, соответствует ли расшифрованное значение исходному значению. Если он не проверяется, он отклоняет связанные данные.

Хакер не может перехватить сообщение от A и подделать ответ, если он не знает секретный ключ B. Хакер не может использовать ранее перехваченный ответ от B, потому что случайная строка каждый раз отличается.

Другие вопросы по тегам