Почему 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&&&
.
Что здесь происходит?
Он предотвращает угон 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 без какой-либо обработки, что приводит либо к бесконечному циклу, либо к синтаксической ошибке.
Это не решает проблему подделки межсайтовых запросов.
Это предотвращает раскрытие ответа через угон JSON.
Теоретически содержимое HTTP-ответов защищено одной и той же политикой происхождения: страницы из одного домена не могут получать какие-либо фрагменты информации со страниц из другого домена (если это явно не разрешено).
Злоумышленник может запросить страницы в других доменах от вашего имени, например, используя <script src=...>
или <img>
, но он не может получить никакой информации о результате (заголовки, содержимое).
Таким образом, если вы посетите страницу злоумышленника, он не сможет прочитать вашу электронную почту с gmail.com.
За исключением того, что при использовании тега сценария для запроса содержимого JSON JSON выполняется как Javascript в среде, контролируемой злоумышленником. Если злоумышленник может заменить конструктор Array или Object или какой-либо другой метод, используемый во время конструирования объекта, все, что в JSON, пройдет через код злоумышленника и будет раскрыто.
Обратите внимание, что это происходит во время выполнения JSON как Javascript, а не во время его анализа.
Есть несколько контрмер:
Размещая некоторое while(1);
Заявление перед данными JSON, Google гарантирует, что данные JSON никогда не выполняются как Javascript.
Только легальная страница может на самом деле получить весь контент, убрав while(1);
и проанализировать остаток как JSON.
Вещи, как for(;;);
например, были замечены на Facebook с такими же результатами.
Аналогичным образом, добавление недопустимых токенов перед JSON, например &&&START&&&
, гарантирует, что он никогда не будет выполнен.
Это рекомендуемый 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.
Это делается для того, чтобы какой-то другой сайт не смог сделать неприятные трюки, чтобы попытаться украсть ваши данные. Например, заменив конструктор array, затем включив этот URL JSON с помощью тега <script>
, сайт-сайт вредоносного third- мог бы украсть данные из ответа JSON. Помещая while(1);
в начале, вместо этого будет script.
A same- запрос сайта с использованием XHR, а отдельный анализатор JSON, с другой стороны, может легко игнорировать префикс while(1);
.
Это было бы затруднительно для сторон third- вставить ответ JSON в HTML-документ с тегом <script>
. Помните, что тег <script>
освобожден от Политика одинакового происхождения.
Object
и Array
, выполнение правильного ответа JSON, как если бы это был JavaScript, было бы абсолютно безвредным при любых обстоятельствах. Да, while(1);
предотвращает выполнение ответа в виде JavaScript, если на него указывает тег <script>
, но ваш ответ не объясняет, почему это необходимо.
Это предотвращает его использование в качестве цели простого тега <script>
. (Ну, это не мешает, но это делает его неприятным.) Таким образом, плохие парни не могут просто поместить этот тег script на свой собственный сайт и полагаться на активный сеанс, чтобы можно было получить ваш контент.
edit — обратите внимание на комментарий (и другие ответы). Проблема связана с подрывными built- на объектах, в частности с конструкторами Object
и Array
. Они могут быть изменены таким образом, чтобы в противном случае безобидный JSON при анализе мог вызвать код злоумышленника.
Object
и Array
, выполнение правильного ответа JSON, как если бы это был JavaScript, было бы абсолютно безвредным при любых обстоятельствах. Да, while(1);
предотвращает выполнение ответа в виде JavaScript, если на него указывает тег <script>
, но ваш ответ не объясняет, почему это необходимо.
Поскольку <script>
освобожден от той же политики происхождения, что является необходимостью безопасности в веб-мире, while(1)
при добавлении в ответ JSON предотвращает его неправильное использование в <script>
.
)]}'
сейчас вместоwhile(1);
? Будут ли ответы такими же?