Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2025-68116 — CVE-2025-68116 的文档 | Kitploit
工具/GitHubGitHub/x0root/cve-2025-68116
漏洞分析漏洞利用Web安全渗透测试论文与研究学习与教育
GitHubx0root/cve-2025-68116

CVE-2025-68116

CVE-2025-68116 的文档

查看仓库
8个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2025-68116

作者:@x0root
漏洞:通过浏览器可渲染的上传文件(SVG / HTML)导致的存储型跨站脚本(XSS)
受影响软件:FileRise(< 2.7.1)
已修复版本:2.7.1
官方 CVE(通过 GHSA 申请):CVE-2025-68116(跟踪/公告:GHSA-35pp-ggh6-c59c)
先前相关公告(被绕过的最初缓解措施):GHSA-qrcv-vjvf-fr29

CVSS 评估:

  • CNA(GitHub):CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:L — 8.9(高)
  • 报告者(作者分析):CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L — 9.6(严重)

CVSS 评分依据(报告者)

报告者的评估在利用时而非植入漏洞时评估所需权限(PR)。

利用发生在受害者访问生成的公共分享链接时,该过程无需身份验证或任何权限(PR:N)。

CNA 的评估基于上传恶意文件的能力来评价 PR。然而,CVSS v3.1 将所需权限(PR)定义为攻击者在漏洞被利用时必须具备的权限,而不是为植入或准备漏洞条件所需的权限。

因此,PR:N 更准确地反映了现实世界的利用条件,从而得出严重(9.6)的严重性等级。

注意:GHSA-qrcv-vjvf-fr29 引入了一项缓解措施,阻止 SVG 在 FileRise Web UI(预览窗格)内渲染。本报告记录了该缓解措施的一种绕过方式——具体针对后端分享/下载端点——对应跟踪编号为 GHSA-35pp-ggh6-c59c / CVE-2025-68116。


摘要

本文档是 CVE-2025-68116 的完整技术记录:FileRise 中一种存储型 XSS,在早期缓解措施之后仍然存在,最终在 v2.7.1 中修复。内容包括发现过程、利用概念验证、多次失败的修复尝试、精确的根因控制流分析(附证据)、补丁的最终验证以及与 CVSS 评估相关的可利用性特征分析。以下所有内容均基于复现测试、控制器代码审查和公开公告线程。


1. 背景:先前公告与不完整的修复

先前的公告 GHSA-qrcv-vjvf-fr29 通过阻止 FileRise Web UI 中的内联渲染来处理通过 SVG 上传导致的存储型 XSS。该缓解措施没有解决后端端点如何提供 SVG 文件的问题,例如:

  • /api/file/download.php
  • /api/file/share.php

CVE-2025-68116(跟踪编号为 GHSA-35pp-ggh6-c59c)记录了针对 GHSA-qrcv-vjvf-fr29 缓解措施的绕过:攻击者可以存储精心构造的 SVG,并通过公共分享链接或某些下载行为将其传递给受害者,导致脚本在 FileRise 源(origin)中执行。


2. 发现:概念验证上传与绕过

为了验证后端是否仍以可渲染的方式暴露 SVG,我上传了一个简单的 PoC SVG:

通过以下方式访问该文件:

  • /api/file/download.php?…
    以及更重要的:
  • /api/file/share.php?token=…

导致 alert() 执行。最初的 GHSA-qrcv-vjvf-fr29 缓解措施(UI 预览阻止)通过直接访问这些端点被绕过。


3. 证明现实世界影响

alert() 只是一个概念验证;我通过让负载与内部 API 交互来测试实际影响。

使用的测试负载:

root@kitploit:~
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript">
    fetch('/api/upload/upload.php')
      .then(response => response.text())
      .then(data => alert('API Response: ' + data));
  </script>
</svg>

当已登录的管理员打开包含此 SVG 的分享链接时,脚本执行并发起了已认证的 API 请求。观察到的效果包括:

  • API 响应返回给脚本(敏感信息可能被泄露)
  • API 响应指示了 CSRF 令牌状态(例如 {"csrf_expired":true,"csrf_token":"..."})
  • 该交互使管理员现有的 CSRF 令牌失效,在恢复之前阻止进一步的状态更改操作(实际上是对管理员功能的拒绝服务)

测试期间展示的影响分类:

  • 机密性:高(C:H)
  • 完整性:高(I:H)
  • 可用性:低(A:L)

4. 披露时间线与反复的修复尝试

我私下报告了该问题。维护者发布了多个增量修复:

  • v2.6.0 — 对下载端点应用了缓解措施;分享端点仍然存在漏洞。
  • v2.6.2 — 进一步尝试;在我的测试中分享端点仍然存在漏洞。
  • v2.7.0 — 声称已强化分享端点;在我的环境中仍然可利用。
  • v2.7.1 — 我验证可解决该问题的最终修复(见验证章节)。

在 v2.6.0 → v2.7.0 期间,分享链接端点持续以允许内联渲染和脚本执行的方式提供 SVG。下面的根因分析解释了为什么早期修复未能完全封堵该攻击向量。


5. 根因分析 — 控制流与标头失效(证据)

根本原因不是缺少某个标头,而是 shareFile()(控制器)内部的控制流和输出顺序问题,导致在许多执行路径上无法应用安全标头。存在两类问题:

  • 多个提前的 exit; 点,在安全标头设置之前就短路了函数。
  • PHP 警告/通知在标头调用之前输出内容,导致“headers already sent”错误。

5.1 提前退出枚举

我使用 awk 扫描来列出 shareFile() 内直到 readfile() 调用之前的 header() 和 exit; 出现位置:

命令:

awk '/function shareFile(/ {flag=1} /readfile(/ {flag=0} flag && /(header|exit;)/ {printf "%4d | %s\n", NR, $0}' src/controllers/FileController.php

观察到的输出(摘自运行结果,已删减):

1649 | header('Content-Type: application/json; charset=utf-8'); 1651 | exit; 1657 | header('Content-Type: application/json; charset=utf-8'); 1659 | exit; 1664 | header('Content-Type: application/json; charset=utf-8'); 1666 | exit; 1670 | header("Content-Type: text/html; charset=utf-8"); 1693 | exit; 1699 | header('Content-Type: application/json; charset=utf-8'); 1701 | exit; 1719 | header('Content-Type: application/json; charset=utf-8'); 1721 | exit; 1725 | header('Content-Type: application/json; charset=utf-8'); 1727 | exit;

安全标头(强化逻辑)从约第 1743 行开始:

1743 | header('X-Content-Type-Options: nosniff'); ... 1770 | header("Content-Disposition: attachment; ...");

由于该函数在许多路径中提前发出标头并 exit;,这些请求永远无法到达设置 Content-Disposition、nosniff 或限制性类型的强化代码。

5.2 密码提示路径

在受密码保护的分享流程中,该函数提前输出了密码提示 HTML:

if (!empty($record['password']) && empty($providedPass)) { header("Content-Type: text/html; charset=utf-8"); ... exit; }

该路径发送 Content-Type: text/html 并在 SVG 强化逻辑之前退出,导致在没有提供密码的受密码保护分享中,浏览器进行内联渲染。

5.3 非密码保护的分享(已演示)

该漏洞并不仅限于受密码保护的流程。在我的测试中,非密码分享请求也返回了 text/html:

命令:

curl -svI "http://127.0.0.1:8080/api/file/share.php?token=437d7913884ace4b94fab8ce745a686a" 2>&1 | grep -iE "content-type"

观察到的结果: < Content-Type: text/html; charset=UTF-8

这证实即使在一般(非密码)情况下,响应也是 text/html,SVG 会内联渲染。

5.4 由于 PHP 通知导致“Headers already sent”

我捕获了对分享端点的原始抓取,其中包含在标头强化之前发出的 PHP 警告。快照(已删减):

命令:

curl -s "http://127.0.0.1:8080/api/file/share.php?token=437d7913884ace4b94fab8ce745a686a" | head -n 30

观察到的原始输出(已删减):

Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1644


Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1645

Warning: Cannot modify header information - headers already sent by (output started at /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php:1644) in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1743

...随后原始 SVG 负载被输出并内联渲染...

这些警告表明在标头强化之前已经产生了输出(弃用通知),使得后续的 header() 调用在这些运行中无法生效。

5.5 根因总结

  • 用于强制下载和设置 nosniff 的强化代码确实存在,但由于提前退出和输出,在许多代码路径中无法到达。
  • PHP 通知/警告进一步阻止了标头的修改。
  • 实际结果:分享链接(某些情况下包括密码和非密码路径)返回 HTML 或以其他方式允许浏览器内联渲染 SVG,从而执行嵌入的脚本。

6. 最终修复(v2.7.1)与验证

在根因报告之后,维护者应用了解决控制流和输出顺序问题的更改。在 v2.7.1 中:

  • SVG/SVGZ 分享链接被强制下载(Content-Disposition: attachment)。
  • SVG 文件以安全的 MIME(application/octet-stream)提供。
  • 应用 X-Content-Type-Options: nosniff。
  • 安全标头逻辑在任何输出之前执行,并且绕过强化的早期 exit; 点已得到纠正/处理。

最终验证(我在 v2.7.1 上的测试):

命令:

curl -svI "http://127.0.0.1:8080/api/file/share.php?token=fc911e48b0a30e9417a9020ef959784d" 2>&1 | grep -iE "content-type|content-disposition"

观察到的结果: < Content-Type: application/octet-stream < Content-Disposition: attachment; filename="xss-image.svg"; filename*=UTF-8''xss-image.svg

结果:浏览器被强制下载;SVG 没有内联渲染,XSS 负载未执行。我认为 v2.7.1 已在我的环境中解决了该问题。


7. CVSS 可利用性背景

可利用性评估(报告者分析)

  • CVSS 评估的是利用时所需的权限,而不是植入时的权限。
  • 此处的利用传递是未认证的:任何公共分享链接的接收者(包括管理员)都可以在无需认证的情况下触发负载。
  • 这创造了一种发射后不管(fire-and-forget)的武器:攻击者植入恶意文件后退出登录,而公共分享链接仍然可利用。
  • 因此,最严重的现实场景对应的正确 CVSS 向量为:

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L — 评分:9.6(严重)

我在公告线程中记录了此依据,并请求使用 PR:N。

维护者评估(已发布)

  • 维护者在官方公告中将所需权限评为低(PR:L),理由是上传/植入恶意文件需要账户或启用了上传的令牌(一种预先存在的能力)。
  • 他们认为该要求属于利用前权限的一部分,因此使用了 PR:L;公告文本仍指出生成的分享 URL 可被未认证的接收者打开。

管理结果

  • 维护者随后通过 GitHub 申请了 CVE,并发布了带有 PR:L(高 8.9)的 GHSA 公告。
  • 该 CVE 作为 GHSA 流程的一部分通过 GitHub 申请,并已以 PR:L 发布。本文档保留了报告者对可利用性特征的技术分析,以供完整性和未来参考。

CNA 的 CVSS 向量反映了一个受限的威胁模型。

经验测试表明存在更严重且可复现的利用路径,这与标准评分规则下更高的 CVSS 3.1 基础评分一致。

鼓励独立评估者使用本文档中描述的观察到的利用条件来评估严重性,确保公开的严重性反映现实世界的影响,而不是一个范围狭窄的基线。


8. 结论

  • 该问题是一个真正的存储型 XSS,SVG 可以以允许内联渲染和脚本执行的方式被提供。
  • 先前的公告(GHSA-qrcv-vjvf-fr29)缓解了预览渲染问题,但没有解决后端分享/下载端点;GHSA-35pp-ggh6-c59c(CVE-2025-68116)记录了这一绕过。
  • 核心技术根因是控制流顺序和输出先于标头,导致安全标头在多个执行路径中无法被应用。
  • v2.7.1 中的最终修复纠正了控制流,强制 SVG 下载,并应用了适当的标头;我已验证该修复。
  • 为保持透明,本文档记录了 CVSS 所需权限(PR:N 与 PR:L)的不同解释。

附录 A — 证据(调查期间捕获的选定片段)

A.1 提前退出标头扫描(awk 输出,已删减)

1649 | header('Content-Type: application/json; charset=utf-8'); 1651 | exit; 1657 | header('Content-Type: application/json; charset=utf-8'); 1659 | exit; 1664 | header('Content-Type: application/json; charset=utf-8'); 1666 | exit; 1670 | header("Content-Type: text/html; charset=utf-8"); 1693 | exit; 1699 | header('Content-Type: application/json; charset=utf-8'); 1701 | exit; 1719 | header('Content-Type: application/json; charset=utf-8'); 1721 | exit; 1725 | header('Content-Type: application/json; charset=utf-8'); 1727 | exit;

安全标头从约 1743 行开始: 1743 | header('X-Content-Type-Options: nosniff'); ... 1770 | header("Content-Disposition: attachment; ...");

A.2 非密码分享 curl 标头(脆弱行为)

~/FileRise $ curl -svI "http://127.0.0.1:8080/api/file/share.php?token=437d7913884ace4b94fab8ce745a686a" 2>&1 | grep -iE "content-type" < Content-Type: text/html; charset=UTF-8

A.3 “Headers already sent”和弃用通知(原始输出示例)

Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1644


Deprecated: Constant FILTER_SANITIZE_STRING is deprecated in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1645

Warning: Cannot modify header information - headers already sent by (output started at /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php:1644) in /data/data/com.termux/files/home/FileRise/src/controllers/FileController.php on line 1743

...随后是 SVG 负载被输出并内联渲染。

A.4 最终验证(v2.7.1)

~/FileRise $ curl -svI "http://127.0.0.1:8080/api/file/share.php?token=fc911e48b0a30e9417a9020ef959784d" 2>&1 | grep -iE "content-type|content-disposition" < Content-Type: application/octet-stream < Content-Disposition: attachment; filename="xss-image.svg"; filename*=UTF-8''xss-image.svg


下载工具