Почему Google работает в то время как (1); на их ответы JSON? - PullRequest
3858 голосов
/ 19 апреля 2010

Почему Google добавляет while(1); к своим (личным) ответам JSON?

Например, вот ответ при включении и выключении календаря в Календарь Google :

while(1);[['u',[['smsSentFlag','false'],['hideInvitations','false'],
  ['remindOnRespondedEventsOnly','true'],
  ['hideInvitations_remindOnRespondedEventsOnly','false_true'],
  ['Calendar ID stripped for privacy','false'],['smsVerifiedFlag','true']]]]

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

Я видел, что это использовалось и в нескольких других местах, но гораздо больше с Google (Почта, Календарь, Контакты и т. Д.) Как ни странно, Документы Google начинаются с &&&START&&& вместо этого, и контакты Google, кажется, начинаются с while(1); &&&START&&&.

Что здесь происходит?

Ответы [ 6 ]

4115 голосов
/ 19 апреля 2010

Это предотвращает захват JSON , серьезную проблему безопасности JSON, формально исправленную во всех основных браузерах с 2011 года с ECMAScript 5.

Придуманный пример: скажем, у Google есть URL-адрес, такой как mail.google.com/json?action=inbox, который возвращает первые 50 сообщений из вашего почтового ящика в формате JSON. Злые сайты в других доменах не могут отправлять AJAX-запросы на получение этих данных из-за политики того же происхождения, но они могут включать URL-адрес через тег <script>. URL посещается с помощью ваших файлов cookie, и переопределяя конструктор глобального массива или методы доступа , они могут иметь метод, вызываемый всякий раз, когда установлен атрибут объекта (массива или хеша), что позволяет им читать содержимое JSON.

while(1); или &&&BLAH&&& предотвращает это: AJAX-запрос на mail.google.com будет иметь полный доступ к текстовому содержимому и может его убрать. Но вставка тега <script> слепо выполняет JavaScript без какой-либо обработки, что приводит либо к бесконечному циклу, либо к синтаксической ошибке.

Это не решает проблему подделки межсайтовых запросов .

524 голосов
/ 02 февраля 2014

Предотвращает раскрытие ответа через угон JSON.

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

Злоумышленник может запрашивать страницы в других доменах от вашего имени, например, используя тег <script src=...> или <img>, но он не может получить никакой информации о результате (заголовки, содержимое).

Таким образом, если вы посещаете страницу злоумышленника, он не может прочитать вашу электронную почту с gmail.com.

За исключением того, что при использовании тега сценария для запроса содержимого JSON JSON выполняется как Javascript в контролируемой среде злоумышленника. Если злоумышленник может заменить конструктор Array или Object или какой-либо другой метод, используемый во время конструирования объекта, все, что в JSON, пройдет через код злоумышленника и будет раскрыто.

Обратите внимание, что это происходит во время выполнения JSON как Javascript, а не во время его анализа.

Существует несколько контрмер:

Убедиться, что JSON никогда не выполняется

Поместив оператор while(1); перед данными JSON, Google гарантирует, что данные JSON никогда не будут выполняться как Javascript.

Только легальная страница может фактически получить весь контент, удалить while(1); и проанализировать остаток как JSON.

Такие вещи, как for(;;); были замечены на Facebook, например, с такими же результатами.

Убедитесь, что JSON не является допустимым Javascript

Аналогично, добавление недопустимых токенов перед JSON, например &&&START&&&, гарантирует, что он никогда не будет выполнен.

Всегда возвращать JSON с Объектом снаружи

Это OWASP рекомендуемый способ для защиты от угона JSON и менее навязчивый.

Подобно предыдущим контрмерам, он гарантирует, что JSON никогда не выполняется как Javascript.

Действительный объект JSON, если он ничем не заключен, недопустим в Javascript:

eval('{"foo":"bar"}')
// SyntaxError: Unexpected token :

Это, однако, допустимый JSON:

JSON.parse('{"foo":"bar"}')
// Object {foo: "bar"}

Таким образом, проверка того, что вы всегда возвращаете Object на верхнем уровне ответа, гарантирует, что JSON не является допустимым Javascript, хотя все еще является допустимым JSON.

Как отметил @hvd в комментариях, пустой объект {} является допустимым Javascript, и знание того, что объект пуст, само по себе может быть ценной информацией.

Сравнение вышеуказанных методов

Способ OWASP менее навязчив, так как не требует изменений клиентской библиотеки и передает допустимый JSON. Однако неизвестно, могут ли прошлые или будущие ошибки браузера победить это. Как отмечает @oriadam, неясно, могут ли данные быть пропущены в результате ошибки синтаксического анализа при обработке ошибок или нет (например, window.onerror).

Google требует клиентскую библиотеку для поддержки автоматической десериализации и может считаться более безопасной в отношении ошибок браузера.

Оба метода требуют изменений на стороне сервера, чтобы разработчики не могли случайно отправить уязвимый JSON.

356 голосов
/ 16 мая 2009

Это сделано для того, чтобы другие сайты не могли делать хитрые уловки, пытаясь украсть ваши данные. Например, заменив конструктор массива , а затем включив этот URL-адрес JSON через тег <script>, злонамеренный сторонний сайт может украсть данные из ответа JSON. Если поставить в начало while(1);, скрипт будет зависать.

С другой стороны, запрос на том же сайте с использованием XHR и отдельного анализатора JSON может легко игнорировать префикс while(1);.

105 голосов
/ 19 апреля 2010

Это может затруднить вставку ответа JSON в документ HTML с тегом <script>. Помните, что тег <script> освобождается от Одинаковой политики происхождения .

77 голосов
/ 19 апреля 2010

Примечание : с 2019 года многие из старых уязвимостей, которые приводят к профилактическим мерам, обсуждаемым в этом вопросе, больше не являются проблемой в современных браузерах. Я оставлю ответ ниже как историческое любопытство, но на самом деле вся тема радикально изменилась с 2010 года (!!), когда об этом спросили.


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

edit & mdash; обратите внимание на комментарий (и другие ответы). Проблема связана с извращенными встроенными средствами, в частности с конструкторами Object и Array. Они могут быть изменены таким образом, чтобы в противном случае безобидный JSON при анализе мог вызвать код злоумышленника.

11 голосов
/ 18 августа 2017

Поскольку тег <script> освобожден от той же политики происхождения, что является необходимостью безопасности в веб-мире, while(1) при добавлении в ответ JSON предотвращает его неправильное использование в теге <script>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...