Open Redirect
Open Redirect — уязвимость, при которой веб-приложение перенаправляет пользователя на произвольный URL из параметра запроса без валидации, что позволяет злоумышленникам создавать фишинговые ссылки с доверенным доменом.
Зачем нужно
Ссылка https://bank.com/login?next=https://evil.com выглядит надёжно, потому что начинается с домена банка. После клика пользователь попадает на фишинговый сайт. Open Redirect используется в фишинге, bypass OAuth-flow и обходе Content-Security-Policy.
Где используется
- Параметры редиректа после логина (
?next=,?redirect=,?returnUrl=) - OAuth callback URL
- Страницы "вы покидаете сайт"
Основной контент
Уязвимый код
// УЯЗВИМО — перенаправляет куда угодно
app.get('/login', (req, res) => {
// После авторизации
res.redirect(req.query.next()); // ?next=https://evil.com
});
Атака через URL-трюки
# Обходы наивной проверки "начинается с /"
https://trusted.com/redirect?to=//evil.com
https://trusted.com/redirect?to=https://evil.com
https://trusted.com/redirect?to=%2F%2Fevil.com (URL-encoded)
https://trusted.com/redirect?to=\/evil.com (backslash)
Безопасный редирект — whitelist подхода
const ALLOWED_PATHS = new Set(['/dashboard', '/profile', '/orders']);
function safeRedirect(res, url) {
try {
// Только относительные пути к нашему домену
const parsed = new URL(url, 'https://example.com');
if (parsed.origin !== 'https://example.com') {
return res.redirect('/');
}
if (!ALLOWED_PATHS.has(parsed.pathname)) {
return res.redirect('/');
}
res.redirect(parsed.pathname + parsed.search);
} catch {
res.redirect('/');
}
}
app.get('/login', authenticate, (req, res) => {
safeRedirect(res, req.query.next() || '/dashboard');
});
Валидация относительных URL
function isRelativeUrl(url) {
// Разрешаем только пути начинающиеся с /
// Отклоняем // (protocol-relative), http://, и т.д.
return /^\/[^/\\]/.test(url);
}
const next = req.query.next();
const redirectTo = isRelativeUrl(next) ? next : '/dashboard';
res.redirect(redirectTo);
Частые ошибки
- Проверка только начала строки:
if (url.startsWith('/'))—//evil.comпройдёт проверку - Использование
url.includes(hostname)—evil.com?trusted.comобойдёт - Доверие заголовку
Refererдля редиректа — легко подделать - Отсутствие fallback на
/при невалидном URL
Связанные темы
- _MOC Безопасность
- Веб-безопасность -- зачем и обзор угроз
- Экранирование и санитизация ввода
- SSRF -- Server-Side Request Forgery