Lichess | 报告 #3165242 - 通过游戏导出API实现的服务器端请求伪造(SSRF)
漏洞概述
报告ID: #3165242
漏洞类型: 服务器端请求伪造(SSRF)
严重程度: 严重(9.8)
报告时间: 2025年5月28日 9:36 AM UTC
报告者: oblivionsage
状态: 已解决并公开披露
漏洞描述
在Lichess的游戏导出功能中发现了一个服务器端请求伪造漏洞。攻击者可以通过操纵players参数,使Lichess服务器向任意URL发送HTTP请求。此漏洞存在于不需要任何身份验证的公共端点上。
技术细节
漏洞代码分析
问题出现在游戏导出API端点中接受players参数的处理过程中。通过代码分析发现:
app/controllers/Game.scala:
|
|
modules/api/src/main/GameApiV2.scala:
|
|
modules/web/src/main/RealPlayer.scala:
|
|
get("players")
方法直接从HTTP查询参数中读取数据,没有任何验证。so()
方法在Option包含值时执行函数,因此提供的任何URL都会直接传递给HTTP客户端。
漏洞验证(PoC)
通过源代码分析发现此漏洞,并在官方Lichess网站上进行了实际测试验证:
- 从Lichess选择任意有效游戏ID
- 向以下端点发送请求:
/game/export/[GAME_ID]?players=http://169.254.169.254/latest/meta-data/
- 服务器将向提供的URL发出HTTP请求
其他可测试的端点:
/api/games/export/_ids?players=[URL]
/api/games/user/[USERNAME]?players=[URL]
可通过监控服务器日志或使用webhook.site等服务来确认请求。
影响分析
攻击者可以利用此漏洞:
- 访问云元数据服务(AWS、GCP)窃取凭据和配置
- 扫描内部网络并发现内部服务
- 访问未暴露到互联网的内部API和管理面板
- 可能读取敏感的内部数据或配置文件
- 对内部基础设施进行端口扫描
由于端点是公开的且不需要身份验证,加上Lichess是高流量网站,攻击者可能利用此漏洞绕过内部服务的基于IP的限制。
修复建议
建议采取以下修复措施:
- 添加URL验证,仅允许特定的受信任域用于players参数
- 实现允许的URL或URL模式的白名单
- 如果功能不关键,考虑完全移除该功能
- 为这些端点添加身份验证要求
- 阻止对私有IP范围的请求(127.x.x.x, 192.168.x.x, 10.x.x.x, 169.254.x.x)
修复应在RealPlayerApi.apply()方法中进行,在发出任何HTTP请求之前验证URL。
修复情况
Lichess团队采取了彻底的修复方案,完全移除了该功能:
- 修复提交:https://github.com/lichess-org/lila/commit/11b4c0fb00f0ffd823246f839627005459c8f05c
- 修复已于2025年6月3日UTC时间8:00部署上线
- 根据监控数据,该功能从未被滥用
影响范围
此漏洞不仅影响主站lichess.org,任何运行自己的Lichess服务器或使用此代码(包括分支和自托管版本)的用户都会受到影响,除非他们打上补丁。
相关资源
- CWE参考: https://cwe.mitre.org/data/definitions/918.html
- 报告已公开披露,CVE编号正在申请中