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

avatar
Jess
19 апреля 2010 в 18:00
561880
8
4271

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

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

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&&&.

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

Источник
Esteban Küber
19 апреля 2010 в 18:04
48

Я считаю, что ваше первое впечатление правильное. Если вы начнете искать код и попытаетесь обрезать входной поток в зависимости от источника, вы передумаете и сделаете это безопасным (а из-за действий Google более простым) способом.

Gizmo
16 февраля 2017 в 18:51
41

возможно, следующий вопрос: почему Google добавляет теперь )]}' вместо while(1);? Были бы ответы такие же?

Mardoxx
6 мая 2017 в 20:27
3

Помешал бы eval, но не с бесконечным циклом.

Gras Double
8 июля 2017 в 20:55
14

Этот )]}' может также использоваться для сохранения байтов, например, в facebook используется for(;;);, который экономит один байт :)

Ответы (8)

avatar
rjh
19 апреля 2010 в 18:11
4437

Он предотвращает захват JSON, серьезную проблему безопасности JSON, которая формально исправлена ​​ во всех основных браузерах с 2011 года с ECC 5.4427804810

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

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

Jakub P.
3 февраля 2013 в 01:43
240

Почему для запроса на получение этих данных вместо этого не требуется CSRF-токен?

Pedro Felix
3 февраля 2013 в 18:26
5

Разве возвращение объекта, содержащего массив, вместо самого массива, также не решило бы проблему?

Boushley
5 февраля 2013 в 02:36
4

@PedroFelix Нет, это не решит проблему, поскольку атаки, упомянутые в сообщении, все еще могут выполняться. Переопределение методов доступа для получения информации.

abraham
5 февраля 2013 в 05:12
191

@JakubP. Хранение и поддержка CSRF-токенов в масштабе Google требует большого объема инфраструктуры и затрат.

bluesmoon
5 февраля 2013 в 06:10
136

@JakubP. токены анти-CSRF мешают кешированию и требуют некоторого количества криптографической оценки на стороне сервера. В масштабе Google для этого потребуется много процессора. Это своего рода разгрузка для клиента.

avatar
MontresorXPL
24 декабря 2020 в 11:43
2

Поскольку это сообщение с высоким трафиком, я надеюсь дать здесь несколько более неопределенный ответ на исходный вопрос и, таким образом, предоставить дополнительную информацию об атаке 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, в POST возвращаются только объекты JSON. запросы.

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

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

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

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

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

avatar
JSON C11
2 марта 2020 в 01:24
0

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

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

avatar
Krishna Ganeriwal
18 августа 2017 в 04:14
12

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

avatar
Arnaud Le Blanc
2 февраля 2014 в 12:09
610

Он предотвращает раскрытие ответа через захват 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.

funroll
15 марта 2014 в 01:47
23

Рекомендация OWASP интересна своей простотой. Кто-нибудь знает причину, по которой способ Google более безопасен?

user719662
12 апреля 2014 в 15:54
18

Я считаю, что не более безопасен в любом случае. Предоставление OWASP здесь кажется достаточным основанием для +1.

Kelsey Francis
29 августа 2014 в 02:19
0

Я предположил, что если вам нужно использовать JSONP, вы можете попытаться использовать токены CSRF каким-нибудь умным (возможно, небезопасным) способом.

avatar
Daniel Vassallo
19 апреля 2010 в 18:04
112

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

avatar
Pointy
19 апреля 2010 в 18:02
83

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


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

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

avatar
bdonlan
16 мая 2009 в 02:08
380

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

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