Jump to content

JSONP

JSONP или JSON-P (JSON с дополнением) — это исторический метод JavaScript для запроса данных путем загрузки <script> элемент, [1] который представляет собой элемент, предназначенный для загрузки обычного JavaScript. Его предложил Боб Ипполито в 2005 году. [2] JSONP позволяет совместно использовать данные в обход политики одного и того же происхождения, которая запрещает запуск кода JavaScript для чтения элементов DOM мультимедиа или данных XMLHttpRequest , полученных за пределами исходного сайта страницы. Исходный сайт обозначается комбинацией схемы URI , имени хоста и номера порта .

JSONP уязвим из-за того, что источник данных заменяет безобидный вызов функции вредоносным кодом, поэтому он был заменен механизмом совместного использования ресурсов между источниками (доступен с 2009 года). [3] ) в современных приложениях.

Функциональность

[ редактировать ]

HTML <script> элементу обычно разрешено выполнять код JavaScript, полученный из сторонних источников. Однако службы, отвечавшие чистыми данными JSON , не могли обмениваться данными из иностранных источников до принятия CORS ( совместное использование ресурсов между источниками ).

Например, запрос в зарубежную службу http://server.example.com/Users/1234 может вернуть запись о человеке по имени Клем в формате JSON. Синтаксис JSON соответствует синтаксису объектов JavaScript.

{
    "Name": "Clem",
    "Id": 1234,
    "Rank": 7
}

Без поддержки CORS попытка использовать данные в разных доменах приводит к ошибке JavaScript.

<script type="application/javascript"
        src="http://server.example.com/Users/1234">
</script>

Браузер загрузит <script> файл, оценить его содержимое, ошибочно интерпретировать необработанные данные JSON как блок и вызвать синтаксическую ошибку. Даже если данные интерпретировались как литерал объекта JavaScript, к ним не мог бы получить доступ JavaScript, запущенный в браузере, поскольку без присвоения переменной литералы объекта недоступны.

В шаблоне использования JSONP URL-запрос, на который указывает src атрибут в <script> Элемент возвращает данные JSON с кодом JavaScript (обычно вызовом функции), заключенным вокруг него. Эта «обернутая полезная нагрузка» затем интерпретируется браузером. Таким образом, функция, которая уже определена в среде JavaScript, может манипулировать данными JSON. Типичный запрос и ответ JSONP показаны ниже.

Вызов функции parseResponse() — это буква «P» в JSONP — «заполнение» или «префикс» вокруг чистого JSON. [4] Чтобы JSONP работал, сервер должен ответить ответом, включающим функцию JSONP. JSONP не работает с результатами в формате JSON. Вызов функции JSONP, который отправляется обратно, и полезные данные, которые получает функция, должны быть согласованы между клиентом и сервером. По соглашению, сервер, предоставляющий данные JSON, предлагает запрашивающему веб-сайту назвать функцию JSONP, обычно используя имя jsonp или обратный вызов в качестве именованного параметра строки запроса, в своем запросе к серверу: <script src="http://server.example.com/Users/1234?callback=parseResponse"></script>.

В этом примере полученная полезная нагрузка будет такой:

parseResponse({"Name": "Clem", "Id": 1234, "Rank": 7});

Внедрение элемента сценария

[ редактировать ]

JSONP имеет смысл только при использовании с элементом сценария. Для каждого нового запроса JSONP браузер должен добавить новый <script> элемент или повторно использовать существующий. Первый вариант — добавление нового элемента сценария — осуществляется посредством динамической манипуляции с DOM и известен как внедрение элемента сценария . <script> элемент вводится в HTML DOM с URL-адресом желаемой конечной точки JSONP, установленным как атрибут «src». Такое динамическое внедрение элемента сценария обычно выполняется с помощью вспомогательной библиотеки JavaScript. jQuery и другие платформы имеют вспомогательные функции JSONP; есть и самостоятельные варианты.

Пример использования jQuery для динамического внедрения элемента сценария для вызова JSONP выглядит следующим образом:

$.getScript("http://server.example.com/Users/192.168.73.96?callback=parseResponse");

После внедрения элемента браузер оценивает его и выполняет HTTP GET для URL-адреса источника, получая содержимое. Затем браузер оценивает возвращаемую полезную нагрузку как JavaScript. Обычно это вызов функции. Таким образом, использование JSONP может позволить страницам браузера работать с политикой одного и того же источника посредством внедрения элемента сценария. [5]

Сценарий выполняется в пределах включаемой страницы и, как таковой, по-прежнему подвергается междоменным ограничениям относительно домена включаемой страницы. Это означает, что веб-страница не может, например, загрузить библиотеку, размещенную на другом сайте, через JSONP, а затем выполнить запросы XMLHttpRequest к этому сайту (если не поддерживается совместное использование ресурсов между источниками (CORS)), хотя такую ​​библиотеку можно использовать для сделать XMLHttpRequests на свой сайт.

Проблемы безопасности

[ редактировать ]

Ненадежный сторонний код

[ редактировать ]

Включение элементов сценария с удаленных серверов позволяет удаленным серверам вставлять любой на веб-сайт контент. Если на удаленных серверах есть уязвимости, позволяющие внедрение JavaScript, страница, обслуживаемая с исходного сервера, подвергается повышенному риску. Если злоумышленник сможет внедрить любой JavaScript в исходную веб-страницу, то этот код сможет получить дополнительный JavaScript из любого домена, минуя политику одного и того же происхождения . [6] HTTP-заголовок политики безопасности контента позволяет веб-сайтам сообщать веб-браузерам, из каких доменных сценариев можно включать.

Примерно в 2011 году была предпринята попытка определить более безопасное строгое определение подмножества для JSONP. [1] что браузеры смогут принудительно выполнять запросы сценариев с определенным типом MIME, например «application/json-p». Если ответ не был проанализирован как строгий JSONP, браузер мог бы выдать ошибку или просто проигнорировать весь ответ. Однако от этого подхода отказались в пользу CORS , а правильный тип MIME для JSONP остался. application/javascript. [7]

Различия в пробелах

[ редактировать ]

JSONP имел те же проблемы, что и разрешение JSON с помощью eval(): оба интерпретируют текст JSON как JavaScript, что означает различия в обработке U+2028 ( разделитель строк ) и U+2029 ( разделитель абзацев ) из собственно JSON. Это сделало некоторые строки JSON незаконными в JSONP; серверы, обслуживающие JSONP, должны были экранировать эти символы перед передачей. [8] Эта проблема теперь исправлена ​​в ES2019. [9]

Манипулирование именами обратного вызова и отраженная атака с загрузкой файла

[ редактировать ]

Несанкционированные имена обратного вызова могут использоваться для передачи вредоносных данных клиентам в обход ограничений, связанных с application/json тип контента, как показано в атаке с отраженной загрузкой файлов (RFD) в 2014 году. [10]

Небезопасные конечные точки JSONP также могут быть заражены вредоносными данными. [11]

Подделка межсайтового запроса

[ редактировать ]

Простое развертывание JSONP подвержено атакам с подделкой межсайтовых запросов (CSRF или XSRF). [12] Поскольку HTML <script> элемент не соблюдает политику одного и того же происхождения в реализациях веб-браузера, вредоносная страница может запрашивать и получать данные JSON, принадлежащие другому сайту. Это позволит оценивать данные в формате JSON в контексте вредоносной страницы, возможно, разглашая пароли или другие конфиденциальные данные, если пользователь в настоящее время вошел в систему на другом сайте.

Розетта Флэш

[ редактировать ]

Rosetta Flash — это метод эксплуатации, который позволяет злоумышленнику использовать серверы с уязвимой конечной точкой JSONP, заставляя Adobe Flash Player полагать, что указанный злоумышленником Flash-апплет создан на уязвимом сервере. Flash Player реализует политику одного и того же источника, позволяющую отправлять запросы (с помощью файлов cookie) и получать ответы от хостинг-сайта. Затем апплет может отправить полученные данные обратно злоумышленнику. Это эксплойт для разных источников, эффект которого аналогичен внедрению произвольного Flash-апплета в уязвимый домен. Эксплойт использует полезную нагрузку ActionScript, скомпилированную в SWF-файл, состоящий полностью из буквенно-цифровых символов, путем создания потока zlib с определенным заголовком и блоков DEFLATE со специальным кодированием Хаффмана . Полученный в результате SWF-файл, содержащий только буквы и цифры, затем используется в качестве параметра обратного вызова вызова JSONP. До июля 2014 года уязвимыми были такие известные сайты, как Google, YouTube, Twitter, Yahoo!, Яндекс, LinkedIn, eBay, GitHub, Instagram и Tumblr. [13] Эту уязвимость первоначально обнаружили Эрлинг и Алок Менграджани во время публичной презентации на конференции по безопасности. Эксплуатация уязвимости была впоследствии улучшена Габором Молнаром. инженер по безопасности Google Мишель Спаньоло. Этот термин придумал [14] и имеет CVE - 2014-4671 [15] и CVE- 2014-5333 . [16] Версия Adobe Flash Player 14.0.0.145, выпущенная 8 июля 2014 г., ввела более строгую проверку файлов Flash, [17] а в версии 14.0.0.176, выпущенной 12 августа 2014 г., исправлено окончательное решение: [18] предотвращение работы этого эксплойта.

До исправления Adobe веб-сайты могли защитить себя, добавляя пустой комментарий JavaScript (/**/) или даже просто новую строку в качестве первых байтов ответа JSONP.

В июле 2005 года Джордж Джемпти предложил добавить к JSON необязательное присвоение переменной. [19] [20] Первоначальное предложение для JSONP, где дополнение является функцией обратного вызова, по-видимому, было сделано Бобом Ипполито в декабре 2005 года. [21] и в настоящее время используется многими приложениями Web 2.0, такими как Dojo Toolkit и Google Web Toolkit .

См. также

[ редактировать ]
  1. ^ Перейти обратно: а б «Более безопасный междоменный Ajax с JSON-P/JSONP» . JSON-P.org . Архивировано из оригинала 4 марта 2016 года . Проверено 30 октября 2011 г.
  2. ^ Ипполито, Боб (5 декабря 2005 г.). «Удаленный JSON — JSONP» . Боб Ипполито о Haskell, Python, Erlang, JavaScript и т . д . Архивировано из оригинала 8 июня 2012 года . Проверено 10 февраля 2017 г. .
  3. ^ «Обмен ресурсами между источниками» . Могу ли я использовать ... Проверено 4 мая 2020 г.
  4. ^ «Экспериментальный набор результатов RDF в переводчик JSON» . Архивировано из оригинала 15 ноября 2014 года . Проверено 20 февраля 2012 г.
  5. ^ «Так как же на самом деле работает JSONP? Несколько простых примеров» . Джейсон Шок . 5 февраля 2013 года . Проверено 26 декабря 2021 г.
  6. ^ Бен Хаяк (17 октября 2014 г.). «Выполнение метода того же происхождения» (PDF) . Проверено 22 октября 2014 г.
  7. ^ Грей, Илай (27 июня 2010 г.). «Безопасно ли это для предоставления JSONP?» . stackoverflow.com . Проверено 7 сентября 2012 г.
  8. ^ «JSON: подмножество JavaScript, которого нет» . Магнус Холм. Архивировано из оригинала 13 мая 2012 года . Проверено 16 мая 2011 г.
  9. ^ «Включить JSON (он же JSON ⊂ ECMAScript)» . Гитхаб . 24 октября 2022 г. Проверено 24 октября 2022 г.
  10. ^ Орен Хафиф (2014). «Отраженная загрузка файла — новый вектор веб-атаки» . ТрастВейв . Проверено 25 марта 2015 г.
  11. ^ «Практическое внедрение JSONP» . 18 января 2017 г.
  12. ^ Гроссман, Иеремия (27 января 2006 г.). «Продвинутые методы веб-атак с использованием GMail» . Проверено 3 июля 2009 г.
  13. ^ Микеле, Спаньоло. «Злоупотребление JSONP с Rosetta Flash» . Архивировано из оригинала 21 июля 2014 года . Проверено 20 июля 2014 г.
  14. ^ «Google — список уязвимостей программного обеспечения, обнаруженных или исправленных сотрудниками Google» . Проверено 29 июля 2014 г.
  15. ^ «MITRE: CVE-2014-4671» . Проверено 29 июля 2014 г.
  16. ^ «MITRE: CVE-2014-5333» . Проверено 21 августа 2014 г.
  17. ^ «Бюллетень по безопасности Adobe APSB14-17» . Проверено 29 июля 2014 г.
  18. ^ «Бюллетень по безопасности Adobe APSB14-18» . Проверено 21 августа 2014 г.
  19. ^ «оценка JSON» . 19 июля 2005 г. Архивировано из оригинала 12 февраля 2006 г.
  20. ^ «json: Сообщение: Re: Комментарии» . 17 августа 2005 г. Архивировано из оригинала 22 июля 2012 г.
  21. ^ «Удаленный JSON — JSONP» . из __future__ import * . Bob.pythonmac.org. 5 декабря 2005 г. Архивировано из оригинала 4 декабря 2009 г. Проверено 8 сентября 2008 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: e14d4e7dc0ccf44e974c45b2cde078e0__1720579020
URL1:https://arc.ask3.ru/arc/aa/e1/e0/e14d4e7dc0ccf44e974c45b2cde078e0.html
Заголовок, (Title) документа по адресу, URL1:
JSONP - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)