CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-53948

CVE-2026-53948: Stored Cross-Site Scripting via File Upload Content-Type Spoofing in Ghost

Alon Barad
Alon Barad
Software Engineer

Aug 5, 2026·6 min read·20 visits

Executive Summary (TL;DR)

Ghost versions 6.19.4 to 6.21.0 are vulnerable to Stored Cross-Site Scripting because they trust client-provided file MIME types during upload. Authenticated users can spoof content types to serve HTML scripts from cloud backends, compromising visitors and administrators. This issue is resolved in version 6.21.1.

CVE-2026-53948 is a stored cross-site scripting (XSS) vulnerability in the Ghost content management system. Affected versions (v6.19.4 up to v6.21.0) trusted the client-supplied Content-Type header during file uploads via the Admin API. This allowed authenticated attackers to upload benignly-named files with executable MIME types (like text/html), executing scripts in visitor browsers when hosted on integrated cloud platforms like S3 or GCS.

Vulnerability Overview

CVE-2026-53948 is a stored cross-site scripting (XSS) vulnerability in Ghost, an open-source content management system designed in Node.js. The vulnerability exists within the application's file upload subsystem accessed via the Admin API. Installations running versions 6.19.4 up to 6.21.0 are vulnerable to this security flaw.

Under normal operations, authorized users utilize the Admin API to upload static assets, such as images, PDFs, and documents. When configured with cloud storage backends like Amazon S3 or Google Cloud Storage, the system relies on stored metadata to determine how files are served to site visitors. Because the system trusted the user-supplied HTTP Content-Type header, attackers could map an arbitrary MIME type to a benign file extension.

The vulnerability is classified under CWE-434: Unrestricted Upload of File with Dangerous Type. Successful exploitation allows an authenticated attacker with minimal privileges to store malicious files that execute arbitrary script context within visitors' or administrators' web browsers. This compromise is particularly severe if the file is served from the same origin as the administrative dashboard.

Root Cause Analysis

The root cause of this vulnerability lies in the implicit trust of client-side inputs within Ghost's core server API code, specifically inside ghost/core/core/server/api/endpoints/files.js. During a file upload request via /ghost/api/admin/files/upload/, the client sends a multipart/form-data request containing the binary file and its metadata. Among these fields is the client-defined Content-Type header, which the backend reads as frame.file.mimetype.

The application server passed this user-controlled MIME type directly into the storage adapter configuration without server-side validation or sanitization. If the site is configured to store media locally, the impact is minimized because the web server typically determines the served mime-type based on the physical file extension. However, cloud storage adapters like Amazon S3 or Google Cloud Storage store the explicit metadata passed during the creation API call.

When a cloud adapter uploads the file, it registers the metadata containing the spoofed content type. The cloud platform later serves the file to the browser with the header specified during storage. Consequently, a request for a seemingly harmless file, such as report.pdf, results in the backend returning a response header of Content-Type: text/html if specified by the attacker.

Code Analysis

The vulnerable implementation in ghost/core/core/server/api/endpoints/files.js demonstrates how the server used the incoming mimetype variable directly. The type key in the storage options object received the raw, unvalidated frame.file.mimetype value from the request structure.

// Vulnerable Code Path
const filePath = await storage.getStorage('files').save({
    name: frame.file.originalname,
    path: frame.file.path,
    type: frame.file.mimetype // Directly trusts client input
});

The patch implemented in commit d659e752d6636144d75b9aa94062cdbc88a16b21 addresses this structural oversight by replacing the reference to frame.file.mimetype with a deterministic, server-determined MIME type. The system now loads the mime-types utility and uses it to parse the extension of the uploaded file's original name.

// Patched Code Path
const storage = require('../../adapters/storage');
const mime = require('mime-types');
 
const controller = {
    // ...
    const filePath = await storage.getStorage('files').save({
        name: frame.file.originalname,
        path: frame.file.path,
        type: mime.lookup(frame.file.originalname) || 'application/octet-stream'
    });

By querying the extension using mime.lookup(), the application guarantees that a file named image.png is registered and served as image/png regardless of what the user specified in the multipart request wrapper. If the extension is unrecognized, the code defaults to the safe fallback value of application/octet-stream, which prompts modern web browsers to download the resource instead of parsing or executing it natively.

Exploitation Scenario

Exploitation of CVE-2026-53948 requires an active account on the target Ghost CMS instance with privileges allowing file uploads, such as a Contributor, Author, or Editor. An attacker begins by crafting an HTML-compliant payload containing their malicious JavaScript. To bypass basic client-side verification or initial administrative inspection, the payload is given a legitimate extension, such as document.pdf or image.jpg.

The attacker then transmits an HTTP POST request targeting the /ghost/api/admin/files/upload/ endpoint using an intercepting proxy or a script. Within the multipart request, the attacker alters the Content-Type header linked to the uploaded file parts to text/html. The server receives the request, stores the binary content, and maps the attacker's text/html designation to the storage metadata registry.

When a victim navigates to the returned asset URL, the hosting bucket replies with the stored content-type rather than evaluating the file suffix. Because the returned header is text/html, the browser runs the embedded script under the target origin's context. This execution bypasses traditional boundaries, allowing access to standard web storage or session tokens.

Impact Assessment

The impact of a stored cross-site scripting vulnerability of this class is significant, particularly within content management systems. Because Ghost serves administrative actions and front-end visitor traffic from the same host by default, an active script payload executing on the main domain can interact directly with the Admin API on behalf of the victim.

If an administrative user is induced to view the uploaded file link, the executing script can perform actions with administrative permissions. This includes creating new admin users, altering system configurations, modifying published articles, or exfiltrating sensitive subscriber databases. For standard visitors, the script can be used to capture credentials via keystroke logging, redirect traffic to malicious domains, or deploy additional browser exploits.

The CVSS v3.1 score of 5.4 is calculated with a Low severity categorization due to the requirements for authentication (PR:L) and user interaction (UI:R). However, in environments where high-privileged users frequently review uploaded media from contributors, the real-world operational risk of administrative takeover is elevated. The impact scope is changed (S:C) because the attack crosses the storage-to-execution boundary within the browser sandbox.

Mitigation & Remediation Guidance

The primary remediation path is upgrading the Ghost installation to version 6.21.1 or later, which completely addresses the root cause of client-trusted MIME types. For installations where immediate upgrades are restricted due to operational deployment cycles, several mitigations should be implemented immediately to reduce exposure.

Administrators should configure their edge reverse proxies or CDNs to append the X-Content-Type-Options: nosniff header to all assets served from the /content/files/ directory. This header prevents modern web browsers from sniffing the content and forces them to align rendering decisions strictly with the declared file extension, neutralizing the HTML payload contained in the pseudo-image file.

Another highly effective defense-in-depth practice is the segregation of media hosting. By configuring the cloud storage adapter to serve files from a separate origin (e.g., ghost-assets.com instead of ghost-site.com), any script execution is restricted to the isolated sandbox domain. This prevents access to administrative sessions and cookies stored on the primary Ghost CMS host under the Same-Origin Policy.

Official Patches

TryGhostOfficial Security Advisory
TryGhostFix commit

Fix Analysis (1)

Technical Appendix

CVSS Score
5.4/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N
EPSS Probability
0.13%
Top 97% most exploited

Affected Systems

Ghost CMS

Affected Versions Detail

Product
Affected Versions
Fixed Version
Ghost
TryGhost
>= 6.19.4, < 6.21.16.21.1
AttributeDetail
CWE IDCWE-434
Attack VectorNetwork
CVSS v3.1 Score5.4 (Medium)
Exploit StatusPoC Concept available
CISA KEV StatusNot listed
ImpactStored Cross-Site Scripting (XSS)

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
T1105Ingress Tool Transfer
Command and Control
CWE-434
Unrestricted Upload of File with Dangerous Type

The product allows the attacker to upload or transfer files of dangerous types that can be automatically processed within the product's environment.

Vulnerability Timeline

Fix commit d659e752d6636144d75b9aa94062cdbc88a16b21 submitted and approved
2026-03-10
Public advisory GHSA-944x-pm95-3jpr published by Ghost
2026-06-24
CVE-2026-53948 published in CVE/NVD catalogs
2026-06-24

References & Sources

  • [1]Official Security Advisory
  • [2]GitHub Fix Commit
  • [3]GitHub Pull Request
  • [4]v6.21.1 Release Notes
  • [5]NVD Entry
  • [6]CVE Org Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 3 hours ago•CVE-2026-11748
6.9

CVE-2026-11748: Unauthenticated LDAP Injection in Central Dogma Server Authentication

An LDAP injection vulnerability exists in the centraldogma-server-auth-shiro module of LY Corporation Central Dogma before version 0.84.0. The search logic dynamically constructs LDAP search filters by interpolating user-provided usernames without escaping RFC 4515 metacharacters. Unauthenticated remote attackers can leverage this flaw to bypass authentication, enumerate directory hierarchies, and access unauthorized resources.

Alon Barad
Alon Barad
3 views•6 min read
•about 4 hours ago•CVE-2026-11746
9.4

CVE-2026-11746: Use of Hard-coded ZooKeeper Replication Secret 'ch4n63m3' in Central Dogma Server

CVE-2026-11746 is a critical vulnerability in Central Dogma Server prior to version 0.84.0, where an embedded ZooKeeper replication secret silently falls back to a publicly known, hard-coded default string ('ch4n63m3'). Remote attackers with access to the replication network can authenticate as legitimate cluster peers, potentially leading to unauthorized data exposure, state manipulation, or complete cluster takeover.

Amit Schendel
Amit Schendel
2 views•6 min read
•about 5 hours ago•CVE-2026-56665
4.2

CVE-2026-56665: Logical Validation Bypass in ZITADEL External JWT Identity Provider

A logical verification flaw in ZITADEL's external JWT Identity Provider validation allows attackers to bypass session expiration checks. If an incoming JWT lacks the 'exp' claim, the system skips validation entirely, creating an indefinitely valid session. This issue has been addressed in versions 3.4.12 and 4.15.2.

Alon Barad
Alon Barad
3 views•7 min read
•about 6 hours ago•CVE-2026-59149
6.5

CVE-2026-59149: Sibling Directory Path Traversal in Mockoon Backend Server

CVE-2026-59149 identifies a directory traversal vulnerability in `@mockoon/commons-server`, the backend mock-server library powering the Mockoon application. The flaw occurs in the path containment validation logic used during raw file response generation. An unauthenticated attacker can exploit this weakness to retrieve arbitrary files from sibling directories sharing a common prefix with the designated static base directory.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 7 hours ago•CVE-2026-59148
8.8

CVE-2026-59148: Unauthenticated Administrative API and CORS Misconfiguration in Mockoon

An in-depth analysis of CVE-2026-59148, a high-severity flaw in Mockoon where unauthenticated administrative endpoints and a wildcard Cross-Origin Resource Sharing (CORS) policy allow remote execution, state poisoning, and credential theft.

Alon Barad
Alon Barad
4 views•6 min read
•about 8 hours ago•CVE-2026-56666
4.8

CVE-2026-56666: Account Takeover via Improper Email Verification in ZITADEL Federated Identity Handler

An improper authentication vulnerability (CWE-287) in ZITADEL's external identity provider handler before version 4.15.3 allows remote attackers to perform complete account takeover. When auto-linking by email is enabled, ZITADEL verifies that the local target account has a verified email address but fails to verify if the external provider confirmed ownership of that same email. Attackers can exploit this by registering an unverified account with a victim's email address on a permissive external provider, leading to unauthorized account binding and persistent access.

Amit Schendel
Amit Schendel
2 views•7 min read