Примечание: следующая статья была опубликована 13.02.2016 на https://FogMarks.com

В этом тематическом исследовании основное внимание уделяется основным аспектам и служебным программам JSON, в частности его методу экранирования.

S
oundCloud.com, как и многие другие, использует JSON для получения информации о пользователе с сервера.
Идея проста: сервер отправляет клиенту HTML (а также Javascript, CSS, изображения и т.д.), а затем код javascript использует AJAX для получения данных с сервера.

В этом случае данные с сервера возвращаются в формате JSON, и код javascript знает, как их проанализировать и вставить данные в нужные места страницы.
Возвращенные данные экранируются (возможно) с помощью механизм JSON escaper, поэтому любые вредоносные полезные нагрузки не будут работать.

Главный вопрос, который следует здесь задать: можем ли мы использовать способ получения данных браузером? Можем ли мы заставить его получать произвольный код HTML или Javascript?

Краткий ответ - нет.
Длинный ответ (через 10 минут после начала исследования) - да.

Сначала я решил сосредоточиться на области уведомлений (https://soundcloud.com/notifications), где я заметил, что запросы AJAX выполняются при прокрутке (для получения старых уведомлений).

Ранее я вставлял некоторые полезные данные в различные места на SoundCloud и анализировал, как AJAX запрашивает дополнительные уведомления.
Чтобы безопасно печатать «плохие» символы (', ”,‹,….), JSON экранирует их с помощью ставить \ char перед любым «плохим» символом.

И я начал думать.

Что, если я сбегу сам? Будет ли JSON по-прежнему ускользать от этого?

Что ж, это так. Механизм скрытого вывода JSON "дважды экранировал" полезные данные, которые уже были экранированы. Все, что оставалось сделать, - это предварительно избежать полезной нагрузки, которая вызвала сохраненный XSS в области уведомлений.

Экранирование JSON должно быть выполнено правильно

Единственная причина, по которой это сработало, - это предположение разработчиков о том, что никто не будет «экранировать» свой ввод перед тем, как отправить его. Механизм JSON всегда экранировал ввод (добавляя перед ним символы "или"). Если вы ожидаете, что ввод пользователя будет выводиться сторонним кодом, вам следует:
1. Никогда не разрешать прямое использование тегов HTML / Script. Если необходимо, разрешите пользователям использовать «специальные символы» для оформления ввода (например, * жирный * вместо ‹b›).
2. Знайте механизм. JSON добавляет перед текстом "или". Поэтому, если вы принимаете эти символы от пользователя, просто закодируйте их в URL.

Я воспользуюсь этой возможностью, чтобы отметить, что группа реагирования SoundCloud была самой быстрой из тех, с которыми я когда-либо работал. Взгляните на график раскрытия информации.

График раскрытия информации

13.02.2016 23:00 - Обнаружена и сообщена уязвимость.
14.02.2016 08:00 - Уязвимость подтверждена Soundcloud.
14.02.2016 14:00 - Уязвимость исправлена, награда назначена (HoF + Swag).