Он предотвращает раскрытие ответа через захват 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.
Я считаю, что ваше первое впечатление правильное. Если вы начнете искать код и попытаетесь обрезать входной поток в зависимости от источника, вы передумаете и сделаете это безопасным (а из-за действий Google более простым) способом.
возможно, следующий вопрос: почему Google добавляет теперь
)]}'
вместоwhile(1);
? Были бы ответы такие же?Помешал бы eval, но не с бесконечным циклом.
Этот
)]}'
может также использоваться для сохранения байтов, например, в facebook используетсяfor(;;);
, который экономит один байт :)