Elido
6 мин чтенияИнженерия

Уязвимости открытого редиректа и как их предотвратить

Открытый редирект позволяет злоумышленнику изогнуть доверенную ссылку в сторону вредоносного сайта. Как работает баг, почему он питает фишинг и серверное исправление, которое его убивает.

Marius Voß
DevRel · edge infra
Ссылка на доверенный домен с параметром редиректа, изгибаемая в сторону вредоносного сайта, и серверная карта соответствия ID-к-URL, блокирующая ее, в брендовой палитре Elido

Открытый редирект - это уязвимость, при которой веб-приложение берет целевой URL из непроверенного пользовательского ввода - обычно из query-параметра вроде ?next= или ?url= - и перенаправляет браузер туда, не проверяя его. Ссылка начинается на домене, которому жертва доверяет, поэтому проходит проверку, а затем тихо приземляет ее куда-то еще. Исправление - не в том, чтобы перестать перенаправлять. Оно в том, чтобы перестать позволять запросу решать, куда идет редирект.

Это различие имеет значение, потому что редиректы повсюду, и большинство из них в порядке. Вход в систему и возврат на нужную вам страницу, передача платежному провайдеру, OAuth-колбэк - все нормально, все это редиректы. Баг, каталогизированный как CWE-601 и сгруппированный под broken access control в OWASP Top 10, - это конкретно тот случай, когда цель приходит из управляемого пользователем ввода и ничто не валидирует ее заранее. Злоумышленник подставляет собственный URL, доверенный сайт перенаправляет на него, и доверие переходит вместе с кликом.

Я провожу свои дни на пути редиректа, так что это тема, по которой у меня есть мнения. Короткие ссылки - это редиректы по определению, что делает вопрос "разве сокращатель - это не просто открытый редирект?" справедливым - и ответ, при правильном исполнении, - чистое нет. Мы дойдем до этого ниже. Если механика редиректов для вас в новинку, типы редиректов - это вводный материал, а как работают сокращатели URL покрывает основы уровня редиректов.

Что такое открытый редирект на самом деле#

Разденьте до механизма. Страница принимает параметр, называющий, куда идти дальше, и использует его в HTTP-редиректе, не подтверждая, что он указывает куда-то разрешенное.

https://trusted.example/login?next=https://evil.example/fake-login

Жертва видит trusted.example спереди и кликает. После входа приложение читает next и выдает редирект на evil.example. Браузер подчиняется, потому что редирект - это всего лишь заголовок Location и статус 3xx - спецификация HTTP прямо определяет это поведение, и у браузера нет способа узнать, что именно эта цель враждебна. Пользователь, наблюдающий, как меняется адресная строка после того, как он уже доверился ссылке, часто этого не замечает.

OWASP прямолинейно описывает основную опасность: имя сервера в модифицированной ссылке идентично исходному сайту, что придает доверие вредоносному редиректу. Уязвимость не в том, что сайт перенаправляет. Она в том, что целевую страницу выбрал посторонний.

Созданная злоумышленником ссылка на доверенном домене, несущая параметр next, который указывает на вредоносный сайт, при этом браузер следует редиректу с доверенного хоста на хост злоумышленника

Почему "безобидный" редирект - это реальная угроза#

Рефлекс - пожать плечами: ну отправляет он кого-то на другой сайт, какой вред. Вред - это заимствованное доверие, и оно масштабируется.

Фишинг - главное применение. Ссылка, которая начинается с банка, SaaS-входа или государственного портала, проплывает мимо быстрой визуальной проверки, которую делает большинство людей, и мимо удивительного количества автоматических фильтров, которые инспектируют только ведущий домен. Жертва попадает на пиксель-в-пиксель подделку страницы входа, которую ожидала, на домене, который выглядел правильно один переход назад, и вводит свой пароль. Ни вредоносного ПО, ни экзотической полезной нагрузки - просто редирект и клон.

Становится хуже, когда редиректы сидят рядом с аутентификацией. Открытый редирект в потоке OAuth может утечь код авторизации или токен на контролируемый злоумышленником redirect_uri, что эскалирует "незначительный" баг в полный захват аккаунта. Вот почему открытые редиректы - это основа отчетов bug-bounty, а не сноска. Тот же трюк также отмывает репутацию: спамеры и операторы вредоносного ПО любят отскакивать через доверенный домен, потому что это проводит их настоящую ссылку мимо блок-листов. Мы покрываем более широкую категорию в чек-листе безопасности сокращателя URL, а угол доверия со стороны посетителя - в безопасны ли сокращатели URL.

Как предотвратить открытые редиректы#

Существует иерархия исправлений, и на ее вершине то, что действительно прекращает проблему. Шпаргалка OWASP ранжирует их, и порядку стоит следовать.

  • Вообще не берите URL из запроса. Пусть клиент отправляет короткое имя, ID или токен, и разрешайте его в полную целевую страницу на сервере. OWASP называет это наивысшей степенью защиты, потому что входящий запрос больше не может назвать произвольную цель. Если этот паттерн звучит знакомо, так и должно быть: именно так работает сокращатель URL.
  • Разрешайте по списку, не запрещайте по списку. Когда вам приходится принять целевую страницу, проверяйте ее по списку доверенных хостов или строгому regex. Allow-список отказывает по умолчанию - все, что явно не разрешено, отвергается. Deny-список пропускает по умолчанию, а злоумышленникам платят за поиск записей, которые вы забыли.
  • Парсите строго. Отвергайте протокол-относительные URL (//evil.example), нормализуйте обратные слеши, декодируйте перед валидацией и относитесь к хосту - а не просто к строковому префиксу - как к тому, что нужно проверять. Большинство обходов фильтров живут в ленивом парсинге.
  • Показывайте промежуточную страницу как подстраховку. Если редирект на внешний сайт неизбежен, проводите его через страницу, которая называет целевую страницу и просит пользователя подтвердить. Это трение, но оно превращает молчаливый редирект в осознанный.

Повторяющаяся тема в том, что безопасные редиректы решаются сервером, из данных, которым сервер уже доверяет - никогда из той строки, что пришла в запросе.

Если вы встраиваете редиректы в продукт и предпочли бы не владеть этим режимом отказа, платформа для разработчиков Elido сопоставляет коды с целевыми страницами на сервере по своему устройству - начните с быстрого старта API и больше никогда не лепите вручную параметр ?url=.

Почему короткие ссылки - это защита, а не баг#

Вот часть, которая удивляет людей. Правильно построенный сокращатель URL - это учебниковая реализация исправления открытого редиректа номер один по версии OWASP.

Когда короткая ссылка создается, ее целевая страница валидируется и сохраняется на сервере, привязанная к короткому коду. Когда кто-то заходит, уровень редиректа ищет этот код и перенаправляет на сохраненную цель. Целевая страница никогда не приходит из входящего запроса - посетитель не может дописать ?url= и изогнуть ссылку куда-то еще, потому что такого параметра, который можно изогнуть, попросту нет. Это ровно то сопоставление токена-к-URL, которое рекомендует OWASP, работающее в продакшене миллионы раз в день. Архитектурно это живет на нашем уровне краевого редиректа, а бюджет задержки, который за это платит, - предмет статьи как достичь p95 под 15 мс для редиректов.

Исправление открытого редиректа: запрос отправляет короткий код, сервер сопоставляет его с целевым URL, который был провалидирован и сохранен в момент создания, так что входящий запрос никогда не может назвать произвольную цель

Честная оговорка: сокращателем все еще можно злоупотребить, просто не через открытый редирект. Если платформа позволяет кому угодно чеканить ссылки на что угодно без сканирования или модерации, злоумышленники используют репутацию ее домена, чтобы замаскировать собственные вредоносные целевые страницы - вот почему ответственные сокращатели сканируют цели и применяют политики против злоупотреблений. Это проблема модерации контента, отличная от изъяна валидации ввода, о котором эта статья, и ее не стоит смешивать. Связанная практика преднамеренного сокрытия целевой страницы покрыта в объяснении клоакинга ссылок и маскировки URL, а социально-инженерный родственник всего этого - враждебные QR-коды - в безопасны ли QR-коды.

Вывод в одну строку#

Если ваш код читает целевую страницу из запроса и перенаправляет на нее, у вас есть открытый редирект, который ждет, чтобы его нашли. Сопоставляйте ID с серверной целью вместо этого, разрешайте по списку все, что не можете избежать брать из ввода, и парсите так, будто ожидаете атаки. Редиректы - это не риск. Риск - позволять запросу выбирать, куда они идут. Разница между 301 и 302 в 301 против 302 редиректов - это сноска рядом с этим одним правилом.

Похожее в блоге#

Попробуйте Elido

Вставьте URL - получите короткую ссылку

Без регистрации. Ссылка живёт 30 дней. Зарегистрируйтесь, чтобы оставить её навсегда.

Бесплатно, без регистрации · 2 в день

Попробуйте Elido

URL-сокращатель с хостингом в ЕС: собственные домены, глубокая аналитика, открытый API. Бесплатный тариф - без банковской карты.

Теги
open redirect vulnerability
open redirect
unvalidated redirect
url redirection attack
url shortener security
redirect validation

Читать дальше