Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2025-68116 — A Documentation of CVE-2025-68116 | Kitploit
Tools/GitHubGitHub/x0root/cve-2025-68116
Vulnerability AnalysisExploitationWeb SecurityPenetration TestingPapers & ResearchLearning & Education
GitHubx0root/cve-2025-68116

CVE-2025-68116

A Documentation of CVE-2025-68116

View Repository
129 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2025-68116

Author: @x0root
Vulnerability: Stored Cross-Site Scripting (XSS) via Browser-Renderable Uploads (SVG / HTML)
Affected Software: FileRise (< 2.7.1)
Patched Version: 2.7.1
Official CVE (requested via GHSA): CVE-2025-68116 (tracking/advisory: GHSA-35pp-ggh6-c59c)
Prior related advisory (original mitigation that was bypassed): GHSA-qrcv-vjvf-fr29

CVSS Assessment:

  • CNA (GitHub): CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:L — 8.9 (High)
  • Reporter (author analysis): CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L — 9.6 (Critical)

CVSS Scoring Rationale (Reporter)

The reporter’s assessment evaluates Privileges Required (PR) at the point of exploitation, not at the point of vulnerability planting.

Exploitation occurs when a victim accesses a generated public share link, which requires no authentication or privileges (PR:N).

The CNA assessment evaluates PR based on the ability to upload a malicious file. However, CVSS v3.1 defines Privileges Required (PR) as the privileges an attacker must possess at the time the vulnerability is exploited, not the privileges required to place or prepare the vulnerable condition.

As such, PR:N more accurately reflects real-world exploitation conditions, resulting in a Critical (9.6) severity classification.

Note: GHSA-qrcv-vjvf-fr29 introduced a mitigation that prevented SVGs from rendering inside the FileRise web UI (preview pane). This report documents a bypass of that mitigation—specifically the backend share/download endpoints—which is tracked as GHSA-35pp-ggh6-c59c / CVE-2025-68116.


Abstract

This document is a complete technical record of CVE-2025-68116: a Stored XSS in FileRise that persisted after an earlier mitigation and was ultimately fixed in v2.7.1. It includes discovery, exploitation proof-of-concepts, repeated failed fixes, a precise root-cause control-flow analysis (with evidence), final verification of the patch, and an analysis of exploitability characteristics relevant to CVSS assessment. All content below is based on reproduced tests, controller inspection, and the public advisory thread.


1. Background: Prior Advisory and Incomplete Fix

A prior advisory, GHSA-qrcv-vjvf-fr29, addressed Stored XSS via SVG uploads by blocking inline rendering in the FileRise web UI. That mitigation did not address how SVG files were served by backend endpoints such as:

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

CVE-2025-68116 (tracked as GHSA-35pp-ggh6-c59c) documents a bypass of the GHSA-qrcv-vjvf-fr29 mitigation: an attacker can store a crafted SVG and deliver it to victims via public share links or certain download behaviours, leading to script execution in the FileRise origin.


2. Discovery: Proof-of-Concept Upload & Bypass

To validate whether the backend still exposed SVGs in a renderable way, I uploaded a simple PoC SVG:

Accessing the file via:

  • /api/file/download.php?…
    and, more importantly, via:
  • /api/file/share.php?token=…

resulted in alert() executing. The original GHSA-qrcv-vjvf-fr29 mitigation (UI preview block) was bypassed by direct access to these endpoints.


3. Proving Real-World Impact

An alert() is a PoC; I tested for meaningful impact by having the payload interact with internal APIs.

Test payload used:

<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>

When a logged-in administrator opened a share link containing this SVG, the script executed and made authenticated API requests. Observed effects included:

  • API responses returned to the script (sensitive information could be exposed)
  • The API response indicated CSRF token state (e.g., {"csrf_expired":true,"csrf_token":"..."})
  • The interaction invalidated the administrator's existing CSRF token, preventing further state-changing actions until recovery (practical denial-of-service against admin functions)

Impact classification demonstrated during testing:

  • Confidentiality: High (C:H)
  • Integrity: High (I:H)
  • Availability: Low (A:L)

4. Disclosure Timeline & Repeated Fix Attempts

I reported the issue privately. The maintainer released several incremental fixes:

  • v2.6.0 — Mitigation applied to download endpoint; share endpoint still vulnerable.
  • v2.6.2 — Further attempts; share endpoint remained vulnerable in my tests.
  • v2.7.0 — Claimed hardening for share endpoint; still exploitable in my environment.
  • v2.7.1 — Final fix that I verified resolves the issue (see Verification section).

Throughout v2.6.0 → v2.7.0, the share link endpoint continued to serve the SVG in a way that allowed inline rendering and script execution. The root cause analysis below explains why the earlier fixes failed to fully close the vector.


5. Root Cause Analysis — Control Flow & Header Failure (Evidence)

The underlying cause was not a single missing header but control-flow and output ordering inside shareFile() (controller) that prevented the security headers from being applied in many execution paths. Two classes of problems were present:

  • Multiple early exit; points that short-circuited the function before security headers were set.
  • PHP warnings/notices that emitted output prior to header calls, causing "headers already sent" errors.

5.1 Early exit enumeration

I used an awk scan to list header() and exit; occurrences within shareFile() up to the readfile() call:

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

Observed output (abridged from my run):

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;

Security headers (the hardening logic) begin at line ~1743:

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

Because the function emits headers + exit; earlier in many paths, those requests never reached the hardening code that sets Content-Disposition, nosniff, or the restrictive type.

5.2 Password prompt path

In the password-protected share flow, the function emitted the password prompt HTML early:

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

This path sends Content-Type: text/html and exits before the SVG hardening logic, causing inline rendering in browsers for password-protected shares where no password was provided.

5.3 Non-password-protected shares (demonstrated)

The vulnerability was not limited to password-protected flows. A non-password share request returned text/html as well in my tests:

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

Observed: < Content-Type: text/html; charset=UTF-8

This confirms that even in the general (non-password) case the response was text/html, and the SVG rendered inline.

5.4 "Headers already sent" due to PHP notices

I captured a raw fetch of the share endpoint which included PHP warnings emitted before header hardening. Snapshot (abridged):

Download Tool