开放重定向(Open Redirect)
登录成功后跳转 ?redirect=、注销跳转、next= 等参数若未校验,攻击者可构造链接:登录可信域名 → 立刻跳到钓鱼站,用户难以察觉。
攻击 URL 示意
text
https://trust.example/login?redirect=https://evil.example/phishing若登录成功后执行:
js
const params = new URLSearchParams(location.search);
const redirect = params.get('redirect');
window.location.href = redirect; // 危险:任意域名用户完成登录后浏览器将被带到恶意站点(可能伪造同款登录框二次盗号)。
不安全代码
js
function afterLogin() {
const u = new URLSearchParams(location.search).get('redirect');
window.location.assign(u || '/');
}安全写法:白名单前缀或路径
js
const ALLOWED_HOSTS = new Set(['app.example.com', 'trust.example.com']);
function safeRedirect(raw) {
if (!raw) return '/home';
try {
const url = new URL(raw, location.origin);
if (!ALLOWED_HOSTS.has(url.hostname)) return '/home';
return url.pathname + url.search + url.hash;
} catch {
return '/home';
}
}
function afterLogin() {
const params = new URLSearchParams(location.search);
window.location.assign(safeRedirect(params.get('redirect')));
}仅允许站内相对路径时更简单:
js
function safeRedirectPath(raw) {
if (!raw || !raw.startsWith('/') || raw.startsWith('//')) return '/home';
return raw;
}服务端侧建议
由服务端签发 一次性、签名过的跳转令牌,或使用固定枚举:redirectId=1 映射到已知路径,避免把完整 URL 交给用户可控参数。
小结
原则:永远不要信任用户提供的完整跳转 URL;使用 白名单域名 / 仅相对路径 / 服务端签发令牌。
