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

3469

Почему 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 (Mail, Calendar, Contacts и т.д.). Как ни странно, Документы Google начинается с &&&START&&&, а Google Contacts начинается с while(1); &&&START&&&.

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

  • 36
    Я считаю, что ваше первое впечатление верно. Если вы начнете искать код и попытаетесь обрезать входной поток в зависимости от источника, вы пересмотрите и сделаете это безопасным (и благодаря действиям Google, более простым) способом.
  • 20
    Вероятно, последующий вопрос: почему Google prepend )]}' сейчас вместо while(1); ? Будут ли ответы такими же?
Показать ещё 3 комментария
Теги:
security

6 ответов

4078
Лучший ответ

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

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

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

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

  • 216
    Почему для запроса на получение этих данных не требуется CSRF-токен?
  • 5
    Разве возвращение объекта, содержащего массив, вместо массива напрямую, также не решит проблему?
Показать ещё 48 комментариев
480

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

  • 20
    Рекомендация OWASP интересна своей простотой. Кто-нибудь знает причину безопасности Google?
  • 14
    Я считаю, что это не более безопасно в любом случае. Предоставление OWASP здесь кажется достаточно веской причиной для +1.
Показать ещё 11 комментариев
332

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

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

  • 0
    Я предполагаю, что XHR может быть выдан только одному серверу домена с аутентификацией. Как «другой сайт» может перехватить ответ? Можете ли вы дать более подробную информацию о том, как «другие сайты» крадут наши данные?
  • 6
    Технически, «нормальный» анализатор JSON должен выдавать ошибку, если у вас есть префикс.
Показать ещё 8 комментариев
96

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

  • 20
    Это только половина ответа. Если бы не хитрость переопределения конструкторов Object и Array , выполнение правильного ответа JSON, как если бы это был JavaScript, было бы абсолютно безвредным при любых обстоятельствах. Да, while(1); предотвращает выполнение ответа в виде JavaScript, если на него указывает тег <script> , но ваш ответ не объясняет, почему это необходимо.
  • 0
    но как это предотвратит фреймы
Показать ещё 2 комментария
68

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

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

  • 15
    Это только половина ответа. Если бы не хитрость переопределения конструкторов Object и Array , выполнение правильного ответа JSON, как если бы это был JavaScript, было бы абсолютно безвредным при любых обстоятельствах. Да, while(1); предотвращает выполнение ответа в виде JavaScript, если на него указывает тег <script> , но ваш ответ не объясняет, почему это необходимо.
7

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню