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

4080

Почему 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 Docs начинается с &&&START&&&этого, а Google Contacts, кажется, начинается с while(1); &&&START&&&.

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

Джесс
источник
45
Я считаю, что ваше первое впечатление верно. Если вы начнете искать код и попытаетесь урезать поток ввода в зависимости от источника, вы пересмотрите и сделаете это безопасным (и благодаря действиям Google, более простым) способом.
Эстебан Кубер
34
Вероятно, последующий вопрос: почему Google предпочитает )]}'сейчас вместо while(1);? Будут ли ответы такими же?
Gizmo
3
Помешал бы eval, но не с бесконечным циклом.
Mardoxx
9
Это )]}'также может быть для сохранения байтов, например, на используемом Facebook, for(;;);который сохраняет один байт :)
Gras Double
3
Для предотвращения раскрытия JSON hijacking
JSON,

Ответы:

4294

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

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

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

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

rjh
источник
228
Почему для запроса на получение этих данных не требуется CSRF-токен?
Якуб П.
235
Делает for(;;);ту же работу? Я видел это в ответах ajax на Facebook.
Король Жюльен
183
@JakubP. Хранение и поддержание CSRF-токенов в масштабах Google требует большого количества инфраструктуры и затрат.
Авраам
127
@JakubP. токены anti-CSRF портят кеширование и требуют некоторой криптографической оценки на стороне сервера. В масштабах Google это потребует много ресурсов процессора. Этот вид разгружает это клиенту.
Bluesmoon
96
Мне кажется, лучшим способом было бы позволить серверу отправлять JSON, только если был установлен правильный заголовок. Это можно сделать с помощью вызова AJAX, но не с помощью тегов сценария. Таким образом, конфиденциальная информация даже не отправляется, и вам не нужно полагаться на безопасность на стороне браузера.
MCV
574

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

Арно Ле Блан
источник
23
Рекомендация OWASP интересна своей простотой. Кто-нибудь знает причину безопасности Google?
funroll
18
Я считаю, что это не более безопасно в любом случае. Предоставление OWASP здесь кажется достаточно веской причиной для +1.
30
Возможно, стоит отметить, почему возвращение литерала объекта приводит к сбою scriptтега или evalфункции. Скобки {}можно интерпретировать как блок кода или литерал объекта, и сам по себе JavaScript предпочитает первый. Как блок кода, он, конечно, недействителен. По этой логике я не вижу никаких ожидаемых изменений в будущем поведении браузера.
Manngo
16
Плохого кода недостаточно, потому что злоумышленник может также захватить обработчик ошибок скрипта браузера ( window.onerror). Я не уверен, каково поведение onerrorс ошибками синтаксиса. Я думаю, Google тоже не был уверен.
Ориадам
12
«Действительный объект JSON, если он ничем не заключен, недопустим в Javascript:» - За исключением тривиального случая пустого объекта ( {}), который также является допустимым пустым блоком. Если знание того, что объект пуст, само по себе может быть ценной информацией, это может быть использовано.
371

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

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

bdonlan
источник
6
Технически, «нормальный» анализатор JSON должен выдавать ошибку, если у вас есть префикс.
Мэтью Крамли
12
Злоумышленники просто используют старый <script>элемент, а не XHR.
Лоуренс Гонсалвес
9
@ Matthew, конечно, но вы можете удалить его перед передачей данных в анализатор JSON. Вы не можете сделать это с <script>тегом
bdonlan
7
Есть ли примеры этого? На замену конструктора массива ссылаются снова, но эта ошибка давно исправлена. Я не понимаю, как можно было бы получить доступ к данным, полученным через тег script. Я хотел бы видеть фиктивную реализацию, которая работает в недавнем браузере.
Деннис G
7
@ joeltine, нет, это не так. См. Stackoverflow.com/questions/16289894/… .
111

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

Даниэль Вассалло
источник
21
Это только половина ответа. Если бы не были уловка переопределяя Objectи Arrayконструкторы, выполняя правильный ответ JSON , как если бы это были JavaScript будет полностью безвредным при любых обстоятельствах. Да, while(1);ответ препятствует выполнению ответа в виде JavaScript, если на него <script>указывает тег, но ваш ответ не объясняет, почему это необходимо.
Марк Амери
но как это предотвратит iframes
Ravinder Payal
Тег сценария никогда не освобождается от политики происхождения. Не могли бы вы прояснить это для меня?
Сурадж Джейн
82

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


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

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

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

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

Кришна Ганеривал
источник
0

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

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

JSON C11
источник