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

Почему 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&&&.

Что тут происходит?


person Jess    schedule 19.04.2010    source источник
comment
Я считаю, что ваше первое впечатление правильное. Если вы начнете искать код и попытаетесь обрезать входной поток в зависимости от источника, вы передумаете и сделаете это безопасным (а из-за действий Google более простым) способом.   -  person Esteban Küber    schedule 19.04.2010
comment
возможно, последующий вопрос: почему Google теперь добавляет )]}' вместо while(1);? Были бы ответы такие же?   -  person Gizmo    schedule 16.02.2017
comment
Помешал бы eval, но не с бесконечным циклом.   -  person Mardoxx    schedule 06.05.2017
comment
Это )]}' может также использоваться для сохранения байтов, например, в facebook используется for(;;);, который сохраняет один байт :)   -  person Gras Double    schedule 08.07.2017


Ответы (8)


Он предотвращает захват 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 без какой-либо обработки, что приводит либо к бесконечному циклу, либо к синтаксической ошибке.

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

person rjh    schedule 19.04.2010
comment
Почему для запроса на получение этих данных вместо этого не требуется CSRF-токен? - person Jakub P.; 03.02.2013
comment
Разве возвращение объекта, содержащего массив, вместо самого массива, также не решило бы проблему? - person Pedro Felix; 03.02.2013
comment
@PedroFelix Нет, это не решит проблему, поскольку атаки, упомянутые в сообщении, все еще могут выполняться. Переопределение методов доступа для получения информации. - person Boushley; 05.02.2013
comment
@JakubP. Хранение и поддержка CSRF-токенов в масштабе Google требует большого объема инфраструктуры и затрат. - person abraham; 05.02.2013
comment
@JakubP. токены анти-CSRF мешают кешированию и требуют некоторого количества криптографической оценки на стороне сервера. В масштабе Google для этого потребуется много процессора. Это своего рода разгрузка для клиента. - person bluesmoon; 05.02.2013

Это предотвращает раскрытие ответа через захват JSON.

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

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

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

За исключением того, что при использовании тега сценария для запроса содержимого JSON JSON выполняется как JavaScript в контролируемой злоумышленником среде. Если злоумышленник может заменить конструктор массива или объекта или какой-либо другой метод, используемый во время создания объекта, все, что в 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"}

Таким образом, если вы всегда возвращаете объект на верхнем уровне ответа, это гарантирует, что JSON не является допустимым JavaScript, но при этом остается действительным JSON.

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

Сравнение вышеперечисленных методов

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

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

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

person Arnaud Le Blanc    schedule 02.02.2014
comment
Рекомендация OWASP интересна своей простотой. Кто-нибудь знает причину, по которой способ Google более безопасен? - person funroll; 15.03.2014
comment
Я считаю, что это не более безопасно. Предоставление OWASP здесь кажется достаточным основанием для +1. - person ; 12.04.2014
comment
Я предположил, что если вам нужно использовать JSONP, вы можете попытаться использовать токены CSRF каким-нибудь умным (возможно, небезопасным) способом. - person Kelsey Francis; 29.08.2014

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

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

person bdonlan    schedule 16.05.2009

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

person Daniel Vassallo    schedule 19.04.2010

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


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

редактировать отметить комментарий (и другие ответы). Проблема связана с искаженными встроенными средствами, в частности конструкторами Object и Array. Их можно изменить так, чтобы безобидный JSON при синтаксическом анализе мог запустить код злоумышленника.

person Pointy    schedule 19.04.2010

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

person Krishna Ganeriwal    schedule 18.08.2017

Поскольку это сообщение с высоким трафиком, я надеюсь дать здесь немного более неопределенный ответ на исходный вопрос и, таким образом, предоставить дополнительную информацию об атаке JSON Hijacking и ее последствиях.

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

[{"id":"1001","ccnum":"4111111111111111","balance":"2345.15"}, 
{"id":"1002","ccnum":"5555555555554444","balance":"10345.00"}, 
{"id":"1003","ccnum":"5105105105105100","balance":"6250.50"}]

Эта атака может быть достигнута за 3 основных шага:

Шаг 1. Заставьте аутентифицированного пользователя посетить вредоносную страницу. Шаг 2. Вредоносная страница будет пытаться получить доступ к конфиденциальным данным из приложения, в которое вошел пользователь. Это можно сделать путем встраивания тега сценария в HTML-страницу, поскольку политика одного и того же происхождения не применяется к тегам сценария.

<script src="http://<jsonsite>/json_server.php"></script>

Браузер отправит запрос GET на json_server.php, и все файлы cookie аутентификации пользователя будут отправлены вместе с запросом. Шаг 3. На этом этапе, пока вредоносный сайт выполнил сценарий, у него нет доступа к каким-либо конфиденциальным данным. Доступ к данным можно получить с помощью установщика прототипа объекта. В приведенном ниже коде свойство прототипов объекта привязывается к определенной функции при попытке установить свойство ccnum.

Object.prototype.__defineSetter__('ccnum',function(obj){
    secrets =secrets.concat(" ", obj);
});

На этом этапе вредоносный сайт успешно захватил конфиденциальные финансовые данные, (ccnum) вернул byjson_server.php JSON.

Следует отметить, что не все браузеры поддерживают этот метод; доказательство концепции было выполнено в Firefox 3.x. Этот метод устарел и заменен на useObject.defineProperty. Также существует вариант этой атаки, который должен работать во всех браузерах, в которых возвращается полное имя JavaScript (например, pi=3.14159) вместо Массив JSON.

Есть несколько способов предотвратить захват JSON:

  • Поскольку теги SCRIPT могут генерировать только запросы HTTP GET, они возвращают только объекты JSON в запросы POST.

  • Запретить веб-браузеру интерпретировать объект JSON как допустимый код JavaScript.

  • Реализуйте защиту от подделки межсайтовых запросов, требуя, чтобы для всех запросов JSON требовалось предварительно определенное случайное значение.

так что, как вы можете видеть, While(1) подпадает под последний вариант. Проще говоря, while(1) - это бесконечный цикл, который будет выполняться до тех пор, пока явно не будет выдан оператор break. И, таким образом, то, что можно было бы описать как блокировку для применяемого ключа (инструкция google break). Поэтому угон JSON, при котором у хакера нет ключа, будет последовательно отклоняться. Увы, если вы читаете блок JSON с помощью парсера, цикл while (1) игнорируется.

Итак, в заключение, цикл while(1) может быть более легко визуализирован как простой шифр оператора прерывания, который Google может использовать для управления потоком данных.

Однако ключевым словом в этом утверждении является слово «простой». Использование аутентифицированных бесконечных циклов, к счастью, было исключено из основной практики в течение с 2010 года из-за абсолютного уменьшения использования ЦП при изолированности (и того факта, что Интернет переместился прочь от грубых «быстрых решений»). Сегодня вместо этого в кодовую базу встроены превентивные меры, и система больше не имеет решающего значения и не эффективна. (отчасти это связано с переходом от JSON Hijacking к более продуктивным методам обработки данных, в которые я сейчас не буду вдаваться)

person MontresorXPL    schedule 24.12.2020

После аутентификации защита от перехвата JSON может принимать различные формы. Google добавляет while (1) в свои данные JSON, поэтому, если какой-либо вредоносный сценарий оценивает его, вредоносный сценарий входит в бесконечный цикл.

Ссылка: Руководство по тестированию веб-безопасности: систематические методы быстрого поиска проблем

person JSON C11    schedule 02.03.2020