Создание AntiForgeryToken через внедрение зависимостей - PullRequest
6 голосов
/ 09 ноября 2009

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

public class AntiForgeryToken
{
    private readonly string _referenceToken;

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

В моем базовом классе для моей MasterPage у меня есть HiddenField, обернутый свойством с именем: 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, хранящий токен внутри сеанса, поэтому он сохраняется для каждого пользовательского сеанса. Будет ли все это допустимой реализацией схемы AntiForgery?

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

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

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

Ответы [ 8 ]

4 голосов
/ 17 ноября 2009

Крис,

Ваш подход более или менее имитирует подход против подделки в MVC, за исключением того, что он использует массив байтов в кодировке base64, сгенерированный из 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/ для анализа + идеи.

2 голосов
/ 16 декабря 2010

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

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

0 голосов
/ 17 ноября 2009

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

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

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

0 голосов
/ 17 ноября 2009

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

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

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

0 голосов
/ 17 ноября 2009

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

Но есть несколько встроенных методов, доступных для этой концепции AntiForgery.

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

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/

Спасибо !!

0 голосов
/ 15 ноября 2009

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

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 10 ноября 2009

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

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

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

...