Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

开放重定向漏洞

| , 4 minutes reading.

1. 定义

开放重定向 (Open Redirect) 漏洞发生在 Web 应用程序接受用户控制的参数,并在未经适当验证的情况下使用它将用户重定向到外部 URL。

虽然开放重定向本身看起来危害较低,但它们对攻击者非常有价值,因为它们滥用了用户对合法域名的信任。使用 trusted-bank.com/redirect?url=evil.com 的钓鱼链接比直接指向 evil.com 的链接看起来更合法。

2. 技术原理

许多合法应用程序需要重定向功能:

  • 登录后重定向:在认证后将用户返回到其原始页面
  • 营销追踪:在到达目的地之前通过追踪系统重定向
  • 单点登录:在身份提供者和应用程序之间重定向

易受攻击的模式:

https://example.com/login?redirect=https://evil.com

成功登录后,应用程序在未经验证的情况下重定向到 evil.com

常见的易受攻击参数:

  • redirectredirect_urireturnreturnUrl
  • nexturltargetdestination
  • continuegotooutredir

绕过技术: 攻击者使用各种技巧绕过弱验证:

# 基本
?redirect=https://evil.com

# 协议相对
?redirect=//evil.com

# 域名混淆
?redirect=https://example.com.evil.com
?redirect=https://[email protected]
?redirect=https://evil.com/example.com

# URL 编码
?redirect=https%3A%2F%2Fevil.com

# 参数污染
?redirect=https://example.com&redirect=https://evil.com

3. 攻击流程

sequenceDiagram
    participant Victim as 受害者
    participant Attacker as 攻击者
    participant TrustedSite as 受信任网站
    participant PhishingSite as 钓鱼网站

    Attacker->>Victim: 发送带有链接的钓鱼邮件<br/>trusted-bank.com/redirect?url=evil.com

    Note over Victim: 链接看起来合法<br/>域名是 trusted-bank.com

    Victim->>TrustedSite: 点击链接到 trusted-bank.com

    TrustedSite->>TrustedSite: 处理重定向参数

    TrustedSite-->>Victim: 302 重定向到 evil.com

    Victim->>PhishingSite: 浏览器跟随重定向

    Note over PhishingSite: 伪造的登录页面<br/>与 trusted-bank.com 完全相同

    Victim->>PhishingSite: 输入凭据

    PhishingSite->>Attacker: 凭据被捕获

4. 真实案例:Google OAuth 开放重定向 (2016)

目标: Google OAuth 2.0 认证流程。 漏洞类别: OAuth 回调中的开放重定向。

漏洞背景: 2016 年,研究员 Egor Homakov 发现 Google 的 OAuth 实现在 redirect_uri 参数验证中存在开放重定向漏洞。

攻击过程:

  1. OAuth 要求应用程序注册允许的 redirect_uri 值。
  2. Google 对某些注册域名的验证过于宽松。
  3. 攻击者可以找到一个在其自身域上存在开放重定向的合法应用程序。
  4. 链条:Google OAuth -> 合法应用(存在开放重定向)-> 攻击者网站。

攻击链示例:

1. 用户点击: accounts.google.com/oauth?redirect_uri=legitimate-app.com
2. Google 验证: legitimate-app.com 已注册 - 通过
3. Google 重定向到: legitimate-app.com/callback?code=AUTH_CODE
4. legitimate-app.com 存在开放重定向: /goto?url=evil.com
5. 攻击者收到: evil.com?code=AUTH_CODE
6. 攻击者用 code 交换访问令牌

影响: 这允许攻击者通过链接漏洞窃取 OAuth 令牌。Google 加强了其 redirect_uri 验证,并鼓励使用更严格的匹配模式。

5. 深度防御策略

A. 白名单验证

仅允许重定向到预先批准的目的地。

const ALLOWED_DOMAINS = [
  'example.com',
  'subdomain.example.com',
  'partner-site.com'
];

function validateRedirect(url) {
  try {
    const parsed = new URL(url);
    return ALLOWED_DOMAINS.includes(parsed.hostname);
  } catch {
    return false;
  }
}

B. 仅允许相对 URL

将重定向限制为相对路径(仅限同源)。

function safeRedirect(url) {
  // 仅允许以 / 开头的路径
  if (url.startsWith('/') && !url.startsWith('//')) {
    return url;
  }
  return '/'; // 默认安全重定向
}

警告: 注意协议相对 URL(//evil.com)。

C. 间接引用映射

使用令牌代替直接 URL。

const REDIRECT_MAP = {
  'dashboard': '/user/dashboard',
  'settings': '/user/settings',
  'logout': '/auth/logout'
};

// 用法: /redirect?target=dashboard
function handleRedirect(target) {
  const destination = REDIRECT_MAP[target];
  if (destination) {
    return redirect(destination);
  }
  return redirect('/');
}

D. 用户确认

对于外部重定向,显示警告页面。

<div class="redirect-warning">
  <h2>您即将离开 example.com</h2>
  <p>您正在被重定向到外部网站:</p>
  <p><strong>https://external-site.com</strong></p>
  <p>我们不对外部网站的内容负责。</p>
  <a href="https://external-site.com">继续</a>
  <a href="/">返回 example.com</a>
</div>

E. 严格的 OAuth 配置

对于 OAuth 实现:

  • 精确匹配: 要求 redirect_uri 精确匹配,而非前缀匹配。
  • 禁止通配符: 避免在注册的重定向 URI 中使用通配符模式。
  • 仅限 HTTPS: 在生产环境中仅允许 HTTPS 重定向 URI。
# 好:仅精确匹配
已注册: https://app.example.com/oauth/callback
有效:   https://app.example.com/oauth/callback
无效:   https://app.example.com/oauth/callback/evil

# 坏:前缀匹配
已注册: https://app.example.com/
有效:   https://app.example.com/anything <- 危险

6. 参考资料