← 返回题目列表

开放重定向是什么?前端跳转参数如何避免被钓鱼利用?

中等 第 17 / 26 题 更新于 2026/07/29
前端安全开放重定向URL钓鱼

简化版

开放重定向是指页面根据用户可控参数直接跳转到任意 URL,例如 ?redirect=https://evil.com,攻击者可以借可信域名外壳诱导用户进入钓鱼站。前端常见场景是登录后回跳、支付完成回跳、活动页跳转。防范方式是只允许站内相对路径或白名单域名,解析 URL 后校验 origin,拒绝协议绕过、双斜杠、编码绕过和 javascript: URL。

详细版

危险代码很常见:

const url = new URLSearchParams(location.search).get('redirect')
if (url) location.href = url

更安全的做法是限制跳转目标。

风险输入问题
https://evil.com直接跳外站
//evil.com协议相对 URL
javascript:alert(1)脚本协议
编码后的外链绕过简单 startsWith

可信域名上的开放重定向,是钓鱼链接最喜欢借用的“门面”。

完整版教学

一、开放重定向为什么危险

用户看到链接域名是可信站点,例如 https://bank.example.com/login?redirect=...,更容易点击。页面加载后再跳到恶意站,用户可能以为仍在可信流程里。

攻击者可以用它做钓鱼、盗号、恶意下载和 OAuth 流程污染。

二、常见业务场景

前端经常需要回跳:

  • 登录成功回到原页面。
  • 支付完成回到订单页。
  • 邀请链接跳活动页。
  • 权限不足跳登录页。

这些场景合理,但跳转目标不能完全由用户决定。

三、只允许相对路径

最简单安全策略是只允许站内相对路径。

function safeRedirect(target: string | null) {
  if (!target || !target.startsWith('/')) return '/'
  if (target.startsWith('//')) return '/'
  return target
}

这样外部域名不会被允许。但还要避免反斜杠、编码等特殊绕过,复杂场景建议用 URL 解析。

四、白名单域名校验

如果确实要跳外部合作域名,应使用白名单。

function isAllowedUrl(raw: string) {
  const url = new URL(raw, location.origin)
  const allowed = new Set([location.origin, 'https://partner.example.com'])
  return ['http:', 'https:'].includes(url.protocol) && allowed.has(url.origin)
}

不要用简单字符串包含判断,例如 url.includes('example.com'),会被 evil-example.com 或用户名字段绕过。

五、协议和编码绕过

攻击者会尝试各种形式:

绕过示例
协议相对//evil.com
用户名混淆https://example.com@evil.com
编码%2f%2fevil.com
脚本协议javascript:alert(1)

所以要规范化解析后再判断。

六、OAuth 场景更敏感

OAuth 的 redirect_uri 必须由授权服务器严格白名单校验。前端自己也不要把登录回跳和 OAuth redirect_uri 混为一谈。

开放重定向如果出现在 OAuth 回调域上,可能导致授权码或 token 泄露。

七、常见误区与追问

  • 误区:跳转是前端行为,不算安全漏洞。 钓鱼、授权码泄露和恶意下载都可能借开放重定向发生。
  • 误区:startsWith 域名就安全。 URL 有用户名、编码、协议相对等绕过方式。
  • 误区:只要是 HTTPS 外链就可以跳。 HTTPS 只保证传输加密,不代表目标可信。
  • 追问:登录后回跳怎么做? 优先只保存站内相对路径,不接受完整外链。
  • 追问:白名单应该怎么写? 解析 URL 后比对精确 origin,不用 contains。
  • 追问:为什么 //evil.com 危险? 它是协议相对 URL,浏览器会按当前协议跳到外部域名。

八、加强记忆

开放重定向记成“可信站帮坏站带路”。回跳参数只认站内相对路径,必须外跳时解析 URL 后比对白名单 origin,拒绝奇怪协议和编码绕过。