Чому Google надає попередній час (1); на їх відповіді JSON?


4074

Чому 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 (пошта, календар, контакти тощо). Як не дивно, Google Документи починають &&&START&&&замість цього, і Google Контакти, здається, починаються з while(1); &&&START&&&.

Що тут відбувається?


45
Я вважаю, що ваше перше враження правильне. Якщо ви почнете шукати код і намагаєтеся обрізати вхідний потік залежно від джерела, ви переглянете та зробите це безпечним (і через дії Google, простішим) способом.
Естебан Кюбер

34
Можливо, наступне питання: Чому Google передує )]}'тепер замість while(1);? Чи відповіді були б однакові?
Gizmo

3
Заважає eval, але не з нескінченною петлею.
Мардокс

9
Це )]}'також може бути для збереження байтів, як у використанні facebook, for(;;);який економить один байт :)
Gras Double

3
Інструкція для запобігання розголошенню json, тобтоJSON hijacking
Ashraf.Shk786

Відповіді:


4293

Це запобігає викрадженню JSON - головного питання безпеки JSON, який офіційно фіксується у всіх основних браузерах з 2011 року за допомогою ECMAScript 5.

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

Це не стосується питання підробки міжміських запитів .


228
Чому запит на отримання цих даних замість цього не вимагає маркер CSRF?
Якуб П.

235
Робить for(;;);ту саму роботу? Я бачив це у відповідях фейсбуку на ajax.
Король Жульєн

183
@JakubP. Зберігання та підтримка CSRF-маркерів у масштабах Google вимагає великої кількості інфраструктури та витрат.
abraham

127
@JakubP. маркери анти-CSRF псуються з кешуванням і вимагають певної кількості серверів криптографічної оцінки. У масштабі Google це вимагатиме багато процесора. Цей вид вивантажує його клієнту.
блюзмоун

96
Мені здається, кращим способом було б дозволити серверу надсилати JSON лише у тому випадку, коли встановлено правильний заголовок. Це можна зробити під час виклику AJAX, але не за допомогою тегів сценарію. Таким чином, конфіденційна інформація ніколи навіть не надсилається, і вам не доведеться покладатися на захист на стороні браузера.
mcv

574

Це запобігає розкриттю реакції через викрадення 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.


23
Рекомендація OWASP цікава завдяки своїй простоті. Хтось знає, чому Google спосіб безпечніший?
funroll

18
Я вважаю, що це не є більш безпечним. Надання OWASP тут здається досить вагомою причиною для +1.

30
Можливо, варто зауважити, чому повернення об'єкта в буквальному сенсі не дає scriptтегу чи evalфункції. Дужки {}можуть бути інтерпретовані як блок коду, так і об'єктний буквал, і сам по собі JavaScript віддає перевагу першому. Що стосується блоку коду, він, звичайно, недійсний. За цією логікою я не бачу передбачуваних змін у майбутній поведінці браузера.
Манго

16
Неправильний код недостатньо, тому що зловмисник також може викрасти передавач скриптів-помилок браузера ( window.onerror) Я не впевнений, що таке поведінка onerrorіз синтаксичними помилками. Я думаю, Google також не був впевнений.
oriadam

12
"Дійсний об'єкт JSON, коли нічим не закритий, не є дійсним у Javascript:" - За винятком тривіального випадку порожнього об'єкта ( {}), який також є дійсним порожнім блоком. Якщо знати, що об’єкт порожній, саме по собі може бути цінною інформацією, це може бути корисно.

371

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

Запит на той самий сайт, що використовує XHR та окремий аналізатор JSON, з іншого боку, може легко ігнорувати while(1);префікс.


6
Технічно "нормальний" аналізатор JSON повинен помилитися, якщо у вас є префікс.
Меттью Крамлі

12
Зловмисники просто використовуватимуть звичайний старий <script>елемент, а не XHR.
Лоранс Гонсальвс

9
@Matthew, звичайно, але ви можете їх видалити, перш ніж передавати дані в аналізатор JSON. Ви не можете цього зробити з <script>тегом
bdonlan

7
Чи є приклади цього? Заміна конструктора масиву знову посилається, але це помилка надовго виправлена. Я не розумію, як можна було б отримати доступ до даних, отриманих через тег скрипту. Я хотів би побачити фіктивну реалізацію, яка працює в останньому браузері.
Dennis 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 додає (1) до своїх даних JSON, так що якщо якийсь шкідливий скрипт оцінює його, шкідливий сценарій потрапляє у нескінченний цикл.

Довідка: Посібник з тестування веб-безпеки: Систематичні методи швидкого пошуку проблем

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.