Яку "конфіденційну інформацію" можна розкрити, встановивши JsonRequestBehavior на AllowGet


112

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

Цей запит було заблоковано, оскільки конфіденційна інформація може бути розкрита стороннім веб-сайтам, коли ця інформація використовується в GET request. Щоб дозволити GET requests, встановіть JsonRequestBehaviorзначення AllowGet.

Замість того, щоб нарікати на підтвердження і звільнити Фіддлера, щоб зробити запит на пошту, цього разу мені цікаво, що це за 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.

Дивіться у цій публікації деякі методи запобігання цьому. Однак це не відома проблема з пізнішими версіями сучасних браузерів (Firefox, Chrome, IE).


25
Приємна публікація, але якщо ви додаєте тег [Авторизувати] до контролера, вам не потрібно турбуватися про безпеку. Сподіваюсь, що цей код допоможе комусь, 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буде містити куки авторизації.
SilverlightFox

1
І якщо дія має будь-які побічні ефекти, її ніколи не слід викликати за допомогою методу GET - умовою є використання GET лише для зчитування даних, а всі побічні дії повинні використовувати POST, PUT, DELETE тощо. Іншими словами, я просто подумайте, що це повідомлення про помилку "конфіденційної інформації" вводить в оману. Якщо розробник використовує метод GET так, як його слід використовувати, тоді все добре! :)
ps_ttf

1
Я не впевнений, яка різниця це все-таки має. Його не схоже повідомлення є більш захищеним або зашифрованим, ніж отримати. Це все ще просто звичайний текст. Я можу надіслати запит так само легко, як повідомлення через будь-який інструмент, і все одно поверну ту саму просту текстову інформацію. Зловмисний користувач може так само легко написати будь-який код сторони сервера на своєму власному сайті, щоб зробити публікацію.
computrius

1
@Castrohenge: Ні, тому що для цього потрібно встановити заголовок, який не надсилатиметься із запитом GET для скрипта src.
SilverlightFox

111

у відповідь використовуйте наступне:

return this.Json("you result", JsonRequestBehavior.AllowGet);

7
Як це насправді відповідає на питання про ОП? Усі ці відповіді - це сказати всім, як обійти виняток ..
eaglei22

2
Так, використовуй .. Це як спробувати ловити з порожнім уловом. НЕ використовуйте цих хлопців (перш ніж зрозуміти ризики). -1'd
sotn

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);
  }

Ось цікава стаття від Phil Haack JSON Hijackingпро те, чому б не використовувати Json методом GET


2
Чудовий пост. Важлива причина, чому ви повинні використовувати HTTPS.
pqsk

6
Я не думаю, що HTTPS тут допомагає.
Шон Макміллан

10

Коли ми хочемо повернути об’єкт json клієнту з програми MVC, ми повинні чітко вказати JsonRequestBehavior.AllowGet при поверненні об'єкта. Як результат, я повертаю дані json як нижче, щоб подолати проблему:

    return Json(yourObjectData, JsonRequestBehavior.AllowGet);

7

Ви повинні використовувати JsonRequestBehavior.AllowGet для відповіді Json таким чином:

return Json(YourObject, JsonRequestBehavior.AllowGet);

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.