В PDF есть одна интересная возможность: отправка кросс-доменных запросов с практически любыми заголовками. Это больше напоминает баг, чем фичу, поэтому, скорее всего, окажется запатчено в будущем. Но за этим багом стоит распространенная проблема, так что о нем стоит поговорить подробнее.

Как мы знаем, Same Origin Policy сильно ограничивает возможности взаимодействия между сайтами. Сейчас мы имеем возможность с помощью JavaScript (а также форм HTML и других методов) отправлять со своего сайта произвольные запросы GET и POST на другие сайты, при этом содержимое запроса может быть любым. Доступны и пользовательские cookie. Еще мы можем задавать значения для некоторых заголовков. Например, content-type, да и то подойдет не любое значение. Ну и конечно же, мы не сможем прочитать ответ сервера.

Если же мы изменим какой-то из неразрешенных заголовков или попытаемся использовать другой метод (к примеру, PUT), то браузер сначала отправит запрос OPTIONS на конечный сервер для того, чтобы узнать, разрешено ли это (CORS в действии). И если разрешения в заголовках нет, то наш запрос отправлен не будет.

А вот с плагином Adobe для просмотра PDF мы имеем возможность ставить любые заголовки! Хотя, конечно, придется покопаться. Потребуется использовать FormCalc и с его помощью отправлять и принимать запросы. Имеется и возможность задавать произвольные заголовки. Но просто так отправить такой запрос на сторонний сайт нельзя — здесь все точно так же, как и в случае с JavaScript.

Однако тут часто встречаются типичные ошибки при работе с Same Origin Policy. Главный источник уязвимостей — это редирект. Теоретически на каждый запрос необходима проверка на SOP, но частенько про это забывают. Все, что нам требуется, — это разместить PDF у себя на сайте. Когда пользователь его открывает, через FormCalc вызывается заранее созданный запрос с произвольными заголовками и происходит перенаправление на наш же сайт. SOP при этом не срабатывает. На сайте мы отвечаем кодом 307 Temporary Redirect. Теоретически FormCalc должен послать CORS-запрос на конечный хост, но он этого не делает. Вместо этого он полностью пересылает запрос со всеми заголовками на конечный хост. Ответ мы получить не сможем, зато этот метод помогает отправлять запросы с произвольными заголовками.

Недавно я сталкивался с приложением, где защита от CSRF была основана лишь на присутствии специального заголовка. Эта возможность PDF могла бы помочь обойти защиту.

Пример PDF можно найти в блоге автора исследования.

Оставить мнение