Oct 8, 2026·6 min read·5 visits
Ghost CMS is vulnerable to a Regular Expression Denial of Service (ReDoS) in its import and migration handlers. Authenticated administrators can cause high CPU utilization and freeze the Node.js event loop by importing directories named with pathological regular expressions or configuring complex migration domain wildcards.
An authenticated Regular Expression Denial of Service (ReDoS) vulnerability in TryGhost Ghost (CMS) versions 4.0.0 through 6.66.x. An attacker with administrator privileges can upload crafted content import archives containing pathological directory names or migration patterns, triggering exponential backtracking in the Node.js V8 engine.
TryGhost Ghost is an open-source content management system (CMS) built on Node.js and the single-threaded V8 JavaScript engine. This architectural design relies on a non-blocking event loop to handle concurrent operations. Any operation that blocks the CPU prevents the event loop from executing other queued tasks, rendering the entire server unresponsive to HTTP requests.
This vulnerability, designated as CVE-2026-105646, belongs to the Regular Expression Denial of Service (ReDoS) class (CWE-1333). It exposes two distinct attack surfaces within the Ghost ecosystem: the archive import mechanism used to migrate content, and the media inliner service used to parse external URLs inside post bodies. An authenticated attacker possessing the Administrator role can abuse these functions to trigger CPU starvation.
The primary entry point occurs during the validation and normalization of file paths within uploaded import ZIP files. Because the application processes these structures dynamically to map import paths, an administrator can supply directory names crafted to induce exponential backtracking. The secondary attack surface exists in the migration domain parsing process, where the application evaluates wildcard domain configurations against large bodies of text without safety boundaries.
The fundamental vulnerability resides in the dynamic, unescaped compilation of regular expression objects using user-controlled parameters. When an administrator imports a package containing structured contents, Ghost identifies the root folder of the ZIP archive. The extracted directory path is stored as baseDir or startDir and subsequently concatenated into a new RegExp('^' + baseDir + '/') instantiation.
In computer science, regular expression engines operating on Nondeterministic Finite Automata (NFA), like the V8 engine, may exhibit exponential time complexity under specific circumstances. If a regular expression contains nested or overlapping quantifiers, such as (a+)+ or (a|a)+, and is evaluated against a partially matching sequence that lacks the terminating character, the engine evaluates every possible grouping permutation. This behavior is called exponential backtracking.
In Vector A, when Ghost processes files, it compares every file path inside the ZIP against the compiled baseDir pattern. If baseDir contains characters like (a+)+b and the target files inside the archive do not match the expected trailing character (e.g., aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/), the engine attempts to evaluate all combinations of the nested loop. This execution blocks the main Node.js thread, preventing the execution of any other asynchronous handlers, networking callbacks, or database operations.
In Vector B, the external-media-inliner.js module performs string matching to find external resources belonging to specific domains. Because migrator systems use wildcard patterns (for example, https?://i[0-9]{1}.wp.com), these rules are compiled directly as regular expressions. Under heavy workloads or with long, complex post contents, evaluating these unconstrained patterns against large text bodies similarly triggers exponential backtracking, starving the server's CPU resources.
An examination of the vulnerable code path prior to the fix commit 88ae6d6d56f8a239cb38a8c89de02f034f50e2ce highlights the absence of string sanitization. In ghost/core/core/server/data/importer/handlers/image.js, the dynamic regular expression was created by raw string addition:
// Vulnerable Implementation
loadFile: function (files, baseDir) {
const store = adapterManager.getAdapter('storage:images');
const baseDirRegex = baseDir ? new RegExp('^' + baseDir + '/') : new RegExp('');
// ...
}To resolve Vector A, the developers integrated Lodash's utility function _.escapeRegExp. This function sanitizes the string by escaping special regular expression characters (^, $, \, ., *, +, ?, (, ), [, ], {, }, |), converting them into literal string characters. Consequently, pathological payloads such as (a+)+b are interpreted as literal matching characters rather than active execution groups.
// Patched Implementation
loadFile: function (files, baseDir) {
const store = adapterManager.getAdapter('storage:images');
const baseDirRegex = baseDir ? new RegExp('^' + _.escapeRegExp(baseDir) + '/') : new RegExp('');
// ...
}For Vector B, wildcards within migration configurations must remain active, which prevents the usage of _.escapeRegExp. To mitigate this, developers isolated the regular expression matching execution inside a node:vm sandbox environment using a configurable timeout parameter. This execution model allows the runtime to abort the CPU-bound calculation if it exceeds the maximum allotted threshold.
// Sandboxed Evaluation with Timeout
function matchAllWithTimeout(content, regex, timeout) {
if (!findMatchesScript) {
findMatchesScript = new vm.Script('Array.from(content.matchAll(regex), (match) => match[1])');
findMatchesContext = vm.createContext({});
}
findMatchesContext.content = content;
findMatchesContext.regex = regex;
try {
return Array.from(findMatchesScript.runInContext(findMatchesContext, { timeout }));
} finally {
findMatchesContext.content = undefined;
findMatchesContext.regex = undefined;
}
}Exploiting this vulnerability requires authenticated access to the Ghost Administration control panel with Administrator privileges. A regular author, editor, or subscriber account does not have authorization to access the server's database or content import endpoints. The attack leverages the import mechanism accessible under the "Labs" or "Settings" sections of the administrative user interface.
The first phase of the attack involves creating a directory name containing a nesting pattern. An attacker can create a folder named (a+)+b on their local filesystem. Within this directory, the attacker inserts files containing long sequences of the matching character followed by a non-matching character, such as aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac.jpg. The attacker then compresses the parent folder into a standard ZIP archive.
mkdir -p "(a+)+b"
touch "(a+)+b/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac.jpg"
zip -r payload.zip "(a+)+b"Once the malicious ZIP file is uploaded to the /ghost/api/admin/db/ endpoint, the server extracts the contents. The import engine resolves the root directory of the archive to determine the base directory prefix. When the import module matches the inner file structures against the dynamic pattern compiled from the directory name, the V8 engine enters a non-terminating evaluation loop, blocking all subsequent thread events.
The recommended remediation is to upgrade the Ghost installation to version 6.67.0 or later. This release completely implements regex sanitization for file import functions and sandboxes external media wildcard evaluations. The updates can be applied using the Ghost command-line interface.
ghost updateIf an immediate upgrade is not feasible, administrators should restrict administrative access to highly trusted staff and enforce Multi-Factor Authentication (MFA). Since the exploitation vector requires administrative capabilities, reducing the number of users with the Administrator role directly limits the threat surface. Audit existing users to ensure only authorized personnel have import capabilities.
Additionally, organizations can configure Web Application Firewall (WAF) rules to inspect multipart form data sent to the Ghost import API endpoints. Specifically, blocking incoming ZIP file uploads that contain special characters like +, (, ), or * within directory or path structures can prevent the payload from reaching the backend extraction handler.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Ghost TryGhost | >= 4.0.0, < 6.67.0 | 6.67.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1333 |
| Attack Vector | Network (AV:N) |
| CVSS | 4.9 (Medium) |
| EPSS | 0.00327 |
| Impact | Denial of Service (DoS) |
| Exploit Status | PoC |
| KEV Status | Not Listed |
The product uses a regular expression that can take a long time to evaluate against specific inputs, leading to a Denial of Service.
CVE-2026-105645 is a regular expression denial of service (ReDoS) vulnerability affecting Ghost, an open-source Node.js content management system. The vulnerability exists within directory import handlers and the external media inliner, allowing authenticated administrators to trigger catastrophic backtracking in the V8 JavaScript engine, resulting in infinite loops, 100% CPU utilization, and total denial of service.
A Stored Cross-Site Scripting (XSS) and Unrestricted Upload of File with Dangerous Type vulnerability in Ghost CMS (versions 4.0.0 to 6.66.x) allows remote attackers to execute arbitrary JavaScript in the context of an administrator's session. The flaw lies in the content import subsystem, which extracted and stored SVG files without sanitization or binary verification.
Stored Cross-Site Scripting (XSS) and origin isolation bypass vulnerability in Ghost CMS versions 6.34.0 through 6.66.1 allows low-privileged staff users to execute arbitrary JavaScript in the context of an administrator session via crafted embed cards.
CVE-2026-105642 is a critical remote code execution vulnerability in Ghost CMS, affecting versions 6.56.0 through 6.66.0. The flaw resides in how Ghost's backend handles external image metadata when generating 'Bookmark' cards in the post editor. When a low-privileged staff member inputs a malicious URL, the server fetches and processes an SVG containing an embedded payload, leading to command execution via the underlying, vulnerable image-processing component.
This report provides a comprehensive technical analysis of CVE-2026-61439 (GHSA-fj8f-m44g-c479), a prompt injection defense bypass vulnerability in the PraisonAI multi-agent framework. In versions prior to 4.6.78, the InjectionDefense scanner threshold defaulted to CRITICAL. This allowed single-vector prompt injections classified as HIGH severity (e.g., direct instruction overrides or financial manipulations) to pass through unblocked, enabling attackers to extract system prompts and execute unauthorized agent tools.
Kunstmaan CMS MediaBundle prior to version 7.3.2 contains a critical file upload vulnerability where case-sensitive extension checks can be bypassed using mixed-case file extensions. Because extension normalization occurs after the validation routine, files with mixed-case executable extensions (such as pHp) bypass checks but are stored with normalized lowercase executable extensions, allowing authenticated administrators to achieve remote code execution.