Вопрос

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

public class AntiForgeryToken
{
    private readonly string _referenceToken;

    public AntiForgeryToken()
    {
        _referenceToken = Guid.NewGuid().ToString();
    }
    public string ReferenceToken
    {
        get { return _referenceToken; }
    }
}

В моем базовом классе для моей MasterPage у меня есть скрытое поле, обернутое свойством с именем: ReferenceToken

protected virtual void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        InjectToken();
    }

    ValidateToken();
}

private void InjectToken()
{
    var token = ObjectFactory.GetInstance<AntiForgeryToken>();
    ReferenceToken = token.ReferenceToken;
}

private void ValidateToken()
{
    var token = ObjectFactory.GetInstance<AntiForgeryToken>();
    if (ReferenceToken.Equals(token.ReferenceToken, SC.InvariantCultureIgnoreCase)) 
            return;
    ...do stuff for failed token
}

У меня есть дескриптор StructureMap, хранящий токен внутри сеанса, поэтому он сохраняется для каждого сеанса пользователя, будет ли все это допустимой реализацией схемы защиты от подделки?

Редактировать: Кажется, в моем вопросе есть некоторая путаница, да, я понимаю ASP.NET MVC имеет встроенную схему AntiForgeryToken, этот вопрос явно касается того, как воссоздать это для Веб-формы чтобы предотвратить использование CSRF-атаки (подделка межсайтовых запросов).Я понимаю, что это никоим образом не устраняет необходимость надлежащей авторизации прав пользователя.

Я собирался привести ту самую ссылку, которую опубликовали @Neal и @solairaja: Предотвратите подделку межсайтовых запросов (CSRF) с помощью ASP.NET Помощника MVC AntiForgeryToken().В этой статье подробнее объясняется, что такое CSRF-атака и как MVC останавливает ее, однако их решение неприменимо к webforms, поэтому я приступил к реализации своего собственного.

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

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

Решение

Крис,

Ваш подход более или менее имитирует подход против FORGEGY в MVC, за исключением того, что они используют кодированный базовый базовый массив, созданный из RNGCRYPTOServiceProvider, и хранят токен как на странице (поле скрытой формы), так и в cookie. Я бы порекомендовал перенести больше логики в реализацию токена (например, инкапсулирует большую часть логики валидации внутри токена).

Код для реализации MVC свободно доступен в http://aspnet.codeplex.com/sourcecontrol/changeset/view/23011?projectname=aspnet#391757 Если возможно, вам, вероятно, следует рассмотреть это, а также http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/ Для анализа + идей.

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

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

Посмотреть состояние предотвращает атаки CSRF
.NET CSRF Guard - OWASP

Во-первых, я полагаю, мне следует спросить...что вы на самом деле подразумеваете под "борьбой с подделкой"?Что вас беспокоит в связи с подделкой?Остальное из того, что следует далее, - это лишь некоторая общая информация, которая приходит на ум...

Одна вещь, которую я бы изменил, это не использовать Guid.NewGuid.Ведутся споры о том, является ли это случайным или нет и, следовательно, не подходит для целей безопасности.Тем не менее, я думаю, что это была бы очень сложная атака.

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

Однако делаете ли вы это через ssl?Во-первых, ssl - это линия защиты номер один для атак "человек посередине".Это может быть недостаточно безопасно (и другие могут спорить об этом) для любых нужд, но если вас беспокоят такие вещи, это, по крайней мере, отправная точка.Если нет, то как вы гарантируете, что получаете ответ от нужной машины, а не от человека посередине, который отвечает первым?Без SSL или его эквивалента ваш токен так же легко украсть, как и все остальное, что вы делаете.

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

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

Пожалуйста, ознакомьтесь также с различными рекомендациями Microsoft по безопасности ASP.NET и IIS (напримерGoogle ASP.NET или IIS security site:microsoft.com) в качестве отправной точки.Многие умные люди уже решили за нас многие вопросы.

будет ли все это действительной реализацией схемы борьбы с подделкой ?

Насколько я могу судить, это выглядит так, как будто вы вставляете GUID на страницу, а затем ищете тот же GUID, когда страница возвращается.

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

  1. Если GUID присутствует только на странице, то что помешает пользователю прочитать страницу на одном компьютере и отправить форму с другого?Было бы неплохо связать его с файлом cookie или сеансом (который также использует файл cookie), если вы этого еще не сделали.
  2. Если GUID записан на страницу как статический скрытый <input> заполните, тогда форма могла бы быть прочитана и отправлена ботами.Вы можете обойти это, потребовав, чтобы скрипт на странице обработал токен перед его отправкой.
  3. Используете ли вы ViewState?Если это так, вы могли бы рассмотреть возможность простой настройки ViewStateUserKey к некоторому повторяющемуся значению, уникальному для каждого клиента;он выполняет функцию, аналогичную той, что вы описали здесь.

Как сказал Ник, для меня тоже код, который вы дали, похоже, что вы вставляете GUID на страницу, а затем ищете ту же GUID, когда страница возвращается. Это хорошая идея, когда ты используешь карту структуры, хранящую в сеансе.

Но есть некоторые встроенные методы для этих концепций антифоргетирования.

Пожалуйста, сначала обратитесь к ссылке ниже и поймите

http://blog.maartenballiauw.be/post/2008/09/01/aspnet-mvc-preview-5s-antiforgerytoken-helper-method-and-attribute.aspx

В настоящее время,

Проверьте ссылку ниже для описания деталей и методологии приближения.

http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper_methods.aspx

http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-%20aspnet-mvcs-antiforgerytoken-helper/

Спасибо !!

Это выглядит для меня так, как будто он генерирует канарейку с каждым запросом. Что произойдет, если пользователь открывает несколько вкладок? :)

Проблема с вашим подходом (и реализация ASP.NET MVC) заключается в том, что она зависит от разработчиков для его реализации. Подобная безопасность должна быть отказана, а не зарегистрировать. Когда я написал Anticsrf Module Вместо этого я использовал жизненный цикл страницы ASP.NET, что означает отсутствие изменений в базовом коде, если разработчик не хотел выбрать страницу из проверки CSRF. Вы заметите, что он использует один токен, который длится для срока службы сеанса браузера этого пользователя - нет реальной необходимости изменить токен с каждым запросом.

Теперь я написал модуль главным образом как способ проиллюстрировать некоторые концепции для моей предстоящей книги (вставьте рекламу здесь ухмылка), вы, конечно, использовать ViewStateUserKey, но опять же, это выбора, а не отказаться.

Первое правило безопасности: Не пытайтесь бросить собственную безопасность

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

Приносим извинения, если я полностью неправильно понял ваше описание ...

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

Например, веб -страница «создать пользовательская страница», я бы проверил, что аутентифицированный пользователь имеет авторизацию для создания новых пользователей. Является ли страница «редактирование пользовательской страницы x», я бы проверил, что у аутентифицированного пользователя есть авторизация для изменения пользователя X. Возможно, потому что он сам является пользователем X или административным пользователем.

Тем не менее, использование GUID не очень безопасно. Гиды генерируются на основе алгоритма, написанного для уникальности, а не случайности. AFAIK Существует три действительных алгоритма, на основе имени, основанных на времени и случайных. Если алгоритм GUID, используемый системой (который может быть изменен в будущей версии .NET), основан на времени, то угадание действительных гид не очень сложно.

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