Какая «конфиденциальная информация» может быть раскрыта при установке JsonRequestBehavior на AllowGet

112

Я получаю одну и ту же старую ошибку каждый раз, когда тестирую новую URLв адресной строке браузера, когда я returning Json(использую встроенный MVC JsonResult helper):

Этот запрос был заблокирован, поскольку конфиденциальная информация может быть раскрыта сторонним веб-сайтам, когда она используется в файле GET request. Чтобы разрешить GET requests, установите JsonRequestBehaviorзначение AllowGet.

Вместо того, чтобы крякать в подтверждение и запускать Fiddler для выполнения почтового запроса, на этот раз мне интересно, что именно представляет собой GETзапрос, а POSTне запрос?

А. Мюррей
источник

Ответы:

82

Допустим, у вашего сайта есть GetUserвеб-метод:

http://www.example.com/User/GetUser/32

который возвращает ответ JSON:

{ "Name": "John Doe" }

Если этот метод принимает только запросы POST, то содержимое будет возвращено в браузер только в том случае, если запрос AJAX выполнен с http://www.example.com/User/GetUser/32использованием метода POST. Обратите внимание: если вы не реализовали CORS , браузер будет защищать данные от других доменов, отправляющих этот запрос к вам.

Однако, если вы разрешили запросы GET, а также сделали запрос AJAX, аналогичный приведенному выше, с GET вместо POST, злонамеренный пользователь может включить ваш JSON в контекст своего собственного сайта, используя scriptтег в HTML. например, на www.evil.com:

<script src="http://www.example.com/User/GetUser/32"></script>

Этот JavaScript должен быть бесполезным, www.evil.comпотому что не должно быть возможности прочитать объект, возвращаемый вашим веб-методом. Однако из-за ошибок в старых версиях браузеров (например, Firefox 3) возможно переопределение объектов-прототипов JavaScript и возможность www.evil.comчтения ваших данных, возвращаемых вашим методом. Это известно как JSON Hijacking.

Посмотрите этот пост, чтобы узнать о некоторых методах предотвращения этого. Однако это не известная проблема в более поздних версиях современных браузеров (Firefox, Chrome, IE).

SilverlightFox
источник
25
Хороший пост, но если вы добавите тег [Authorize] к контроллеру, вам не нужно беспокоиться о безопасности. Надеюсь, этот код кому-то поможет, Json (returnMsg, JsonRequestBehavior.AllowGet)
Dhanuka777
17
@ Dhanuka777: К сожалению, неправда. CSRF- атаки могут быть возможны, если метод имеет побочные эффекты (например www.example.com/User/DeleteUser/32), поскольку запрос будет включать файлы cookie, необходимые для аутентификации, поскольку они поступают с машины жертвы. [Authorize]не спасет вас от атаки, описанной здесь, и в случае очень старого браузера - это сам пользователь, www.evil.comпоэтому запрос, www.evil.comсделанный в, www.example.comбудет содержать файл cookie авторизации.
SilverlightFox
1
И если у действия есть какие-либо побочные эффекты, его никогда не следует вызывать с помощью метода GET - по соглашению GET используется только для чтения данных, а все операции с побочными эффектами должны использовать POST, PUT, DELETE и т. Д. Другими словами, я просто подумайте, что это сообщение об ошибке «конфиденциальная информация» вводит в заблуждение. Если разработчик использует метод GET так, как он должен быть, то все в порядке! :)
ps_ttf 06
1
Я до сих пор не уверен, какая разница. Это не похоже на то, что пост более защищен или зашифрован, чем его получить. Это по-прежнему простой текст. Я могу отправить запрос так же легко, как и отправить сообщение с помощью любого инструмента, и при этом получить обратно ту же текстовую информацию. Злоумышленник может так же легко написать любой код на стороне сервера на своем собственном сайте, чтобы сделать публикацию.
computrius
1
@Castrohenge: Нет, потому что для этого необходимо установить заголовок, который не будет отправлен с запросом GET для скрипта src.
SilverlightFox
111

взамен используйте следующее:

return this.Json("you result", JsonRequestBehavior.AllowGet);
Старый поезд
источник
7
Как это на самом деле отвечает на вопрос ОП? Все, что этот ответ говорит всем, как обойти исключение ..
eaglei22
2
Ага, используй .. Это как попробовать поймать с пустым уловом. НЕ используйте этих парней (пока вы не осознаете риски). -1'd
сотн
6
Безответственно просить людей игнорировать предупреждение системы безопасности, по крайней мере, не объясняя последствий. -1
Эдуардо Вада
58

По умолчанию платформа ASP.NET MVC не позволяет вам отвечать на запрос GET с полезной нагрузкой JSON, так как есть шанс, что злоумышленник может получить доступ к полезной нагрузке с помощью процесса, известного как JSON Hijacking. Вы не хотите возвращать конфиденциальную информацию, используя JSON в запросе GET.

Если вам нужно отправить JSON в ответ на GET и не раскрывать конфиденциальные данные, вы можете явно разрешить такое поведение, передав методу JsonRequestBehavior.AllowGetв качестве второго параметра Json.

Такие как

  [HttpGet] //No need to decorate, as by default it will be GET
  public JsonResult GetMyData(){  
    var myResultDataObject = buildMyData(); // build, but keep controller thin
    // delegating buildMyData to builder/Query Builder using CQRS makes easy :)
    return Json(myResultDataObject, JsonRequestBehavior.AllowGet);
  }

Вот интересная статья Фила Хаака JSON Hijackingо том, почему бы не использовать Json с методом GET.

Мурали Муругесан
источник
2
Отличный пост. Хорошая причина, по которой вы должны использовать HTTPS.
pqsk
6
Я не думаю, что здесь помогает HTTPS.
Шон Макмиллан
10

Когда мы хотим вернуть объект json клиенту из приложения MVC, мы должны явно указать JsonRequestBehavior.AllowGet при возврате объекта. В результате я возвращаю данные json, как показано ниже, чтобы решить проблему:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);
Loc Huynh
источник
7

Вы должны использовать JsonRequestBehavior.AllowGet для ответа Json следующим образом:

return Json(YourObject, JsonRequestBehavior.AllowGet);
Кейван Кашани
источник
0

return Json ("Успех", JsonRequestBehavior.AllowGet)

Пергин Шени
источник