ASP.Net MVC CSRF Предотвращение для JSON POST - PullRequest
15 голосов
/ 01 сентября 2011

Я бы хотел закрыть уязвимость CSRF для публикации необработанного JSON через AJAX.

Я знаком с механизмом MVC для автоматизации предотвращения CSRF с использованием ValidateAntiForgeryTokenAttribute и @Html.AntiForgeryToken();однако, если я правильно понимаю, этот механизм требует, чтобы POST был выполнен с Content-Type из application/x-www-form-urlencoded (или аналогичным).Существует ли в ASP.Net MVC встроенный механизм, который отклоняет CSRF для POST запросов с Content-Type из application/json?Если нет, то застрял ли я в том, чтобы поместить анти-подделку в сам объект JSON?Можете ли вы порекомендовать метод защиты запросов JSON POST от уязвимости CSRF с тем же уровнем безопасности, что и основанный на формах подход, встроенный в ASP.Net MVC?

1 Ответ

9 голосов
/ 01 сентября 2011

Этот вопрос вызывает интересную дискуссию.

При условии, что запрос Content-Type равен application/json, тогда CSRF не имеет значения. Это связано с тем, что запросы application / json должны быть отправлены через XmlHttpRequest, а cookie-файл, который является необходимой частью проверки вашего AntiForgeryToken, не может быть передан между сайтами, но должен соответствовать Политика одинакового происхождения .

Однако, злоумышленник может отправить запрос через application/x-www-form-urlencoded, который содержит информацию, которая будет являться действительным запросом JSON, и которая передаст любые файлы cookie авторизации обратно вашему приложение. Более подробное обсуждение этого вопроса можно получить в http://forums.asp.net/t/1624454.aspx/1?MVC3+JSON+Model+binding+not+working+with+AntiForgery и http://aspnet.codeplex.com/workitem/7472,, где я публикую подтверждение концепции.

Хотя можно включить __RequestVerificationToken в запрос JSON, более эффективная линия защиты - создать атрибут для проверки того, что запрос имеет тип application/json, поскольку любой другой запрос, отправляемый вашему действию, которое ожидает JSON на самом деле недействителен и не должен обрабатываться.

Я ожидаю, что эта проблема безопасности будет решена в MVC 4.

UPDATE:

Вот простой AuthorizeAttribute класс, который вы можете использовать для оформления любых действий, ожидающих получения JSON:

public class JsonRequestAttribute : AuthorizeAttribute
{

    /*
     * 
     *   CONFIRM that this is REALLY a JSON request.
     *   This will mitigate the risk of a CSRF attack
     *   which masquerades an "application/x-www-form-urlencoded" request
     *   as a JSON request
     * 
     */

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
         if (!filterContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
         {
             // This request is masquerading as a JSON request, kill it.
             JsonResult unauthorizedResult = new JsonResult();
             unauthorizedResult.Data = "Invalid request";
             unauthorizedResult.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
             filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest;
             filterContext.Result = unauthorizedResult;
         }
    }
}
...