Вопрос

Это связано с еще один вопрос, который я задал.Таким образом, у меня есть особый случай URL-адреса, где, когда на него отправляется форма, я не могу полагаться на файлы cookie для аутентификации или для поддержания сеанса пользователя, но мне каким-то образом нужно знать, кто они, и мне нужно знать, что они вошли в систему!

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

Основной недостаток безопасности, который я вижу, - это повторные атаки.Как мне помешать кому-либо получить доступ к этой зашифрованной строке и опубликовать ее от имени этого пользователя?Я знаю, что могу использовать SSL, чтобы затруднить кражу этой строки, и, возможно, я смогу регулярно менять ключ шифрования, чтобы ограничить количество времени, на которое годится строка, но я бы действительно хотел найти пуленепробиваемое решение.У кого-нибудь есть какие-нибудь идеи?Предотвращает ли ASP.Net ViewState воспроизведение?Если да, то как они это делают?

Редактировать:Я надеюсь на решение, которое не требует ничего, хранящегося в базе данных.Состояние приложения было бы нормальным, за исключением того, что оно не выдержит перезапуска IIS или вообще не будет работать в сценарии веб-фермы или сада.На данный момент я принимаю ответ Криса, потому что я не уверен, что это вообще возможно обезопасить без базы данных.Но если кто-то предложит ответ, который не связан с базой данных, я приму его!

Это было полезно?

Решение

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

Другие советы

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

{Ts, U, HMAC({Ts, U}, Ks)}

Где Ts - временная метка, U - имя пользователя, а Ks - секретный ключ сервера.Пользователь отправляет это обратно на сервер, и сервер проверяет это, повторно вычисляя HMAC на основе предоставленных значений.Если оно действительное, вы знаете, когда оно было выдано, и можете проигнорировать его, если оно старше, скажем, 5 минут.

Хорошим ресурсом для такого типа разработки является Что делать и чего не делать при аутентификации клиента в Интернете

Здесь есть несколько хороших ответов, и, собрав их все вместе, мы в конечном счете получим ответ:

  1. Блочный шифр шифрует (с помощью AES-256 +) и хэширует (с помощью SHA-2 +) всю информацию, связанную с состоянием / одноразовым номером, которая отправляется клиенту.Хакеры в противном случае просто манипулируют данными, просматривают их, чтобы изучить закономерности, и обходят все остальное.Помни ...для этого требуется всего одно открытое окно.

  2. Генерируйте одноразовый случайный и уникальный одноразовый номер для каждого запроса, который отправляется обратно вместе с запросом POST.Это делает две вещи:Это гарантирует, что ответ POST будет отправлен вместе с ЭТИМ запросом.Это также позволяет отслеживать одноразовое использование данного набора пар get / POST (предотвращая повторение).

  3. Используйте временные метки, чтобы сделать пул одноразовых номеров управляемым.Сохраните временную метку в зашифрованном файле cookie в соответствии с пунктом 1 выше.Отбрасывайте все запросы старше максимального времени ответа или сеанса для приложения (например, часа).

  4. Сохраните "достаточно уникальный" цифровой отпечаток пальца устройства, отправляющего запрос, с зашифрованными данными временной метки.Это предотвратит другой трюк, при котором злоумышленник крадет файлы cookie клиентов для выполнения перехвата сеанса.Это гарантирует, что запрос возвращается не только один раз, но и с компьютера (или достаточно близко, чтобы злоумышленнику было практически невозможно скопировать форму), на который была отправлена форма.

Существуют приложения на основе фильтров безопасности ASPNET и Java / J2EE, которые выполняют все вышеперечисленное с нулевым кодированием.Управление пулом одноразовых номеров для крупных систем (таких как биржевая компания, банк или защищенный сайт большого объема) - непростая задача, если критична производительность.Я бы порекомендовал посмотреть на эти продукты, а не пытаться запрограммировать это для каждого веб-приложения.

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

В одном из моих приложений, чтобы остановить атаки "повтора", я вставил информацию об IP-адресе в свой объект сеанса.Каждый раз, когда я обращаюсь к объекту сеанса в коде, я обязательно передаю запрос.UserHostAddress с ним, а затем я сравниваю, чтобы убедиться, что IP-адреса совпадают.Если они этого не делают, то, очевидно, кто-то другой, кроме этого человека, сделал этот запрос, поэтому я возвращаю null.Это не лучшее решение, но это, по крайней мере, еще один барьер для предотвращения повторных атак.

Можете ли вы использовать память или базу данных для поддержания Любой информация о пользователе или запросе вообще?

Если это так, то по запросу формы я бы включил скрытое поле формы, содержимым которого является случайно сгенерированное число.Сохраните этот токен в контексте приложения или в каком-либо хранилище (базе данных, плоском файле и т.д.) При визуализации запроса.Когда форма отправлена, проверьте контекст приложения или базу данных, чтобы узнать, является ли этот случайно сгенерированный номер все еще действительным (как бы вы ни определяли valid - возможно, срок его действия истечет через X минут).Если это так, удалите этот токен из списка "разрешенных токенов".

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

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

(Повторные атаки легко могут быть связаны с подменой IP / MAC, плюс вам грозит опасность на динамических IP-адресах)

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

ASP.Net ViewState - это беспорядок, избегайте его.Хотя PKI тяжеловесен и раздут, по крайней мере, он работает без изобретения собственных "схем" безопасности.Так что, если бы я мог, я бы использовал это и всегда пользовался взаимной аутентификацией.Аутентификация только на сервере совершенно бесполезна.

ViewState включает в себя функции безопасности.Видишь эта статья о некоторых встроенных функциях безопасности в ASP.NET .Он выполняет проверку по машинному ключу сервера в machine.config на сервере, что гарантирует, что каждая обратная передача действительна.

Далее в статье, вы также видите, что если вы хотите сохранить значения в своих собственных скрытых полях, вы можете использовать LosFormatter класс для кодирования значения тем же способом, который ViewState использует для шифрования.

private string EncodeText(string text) {
  StringWriter writer = new StringWriter();
  LosFormatter formatter = new LosFormatter();
  formatter.Serialize(writer, text);
  return writer.ToString();
}

Если вы принимаете каждый ключ только один раз (скажем, присваиваете ключу GUID, а затем проверяете, когда он возвращается), это предотвратит повторы.Конечно, если злоумышленник ответит Первый, тогда у вас возникает новая проблема...

Это WebForms или MVC?Если это MVC, вы могли бы использовать токен защиты от подделки.Похоже, что это похоже на подход, о котором вы упомянули, за исключением того, что он использует в основном GUID и устанавливает файл cookie со значением guid для этого сообщения.Подробнее об этом читайте в блоге Стива Сандерсона: http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/

И еще, рассматривали ли вы возможность проверки реферера при обратной отправке?Это не пуленепробиваемый материал, но он может помочь.

Используйте https...в него встроена защита от повторного воспроизведения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top