Aug 5, 2026·7 min read·52 visits
Server-Side Request Forgery (SSRF) in Ghost CMS (versions < 6.54.1) allows authenticated staff-level users to execute arbitrary HTTP GET requests targeting local or private network services through the admin console's image processing module.
A comprehensive technical analysis of CVE-2026-70591, a Server-Side Request Forgery (SSRF) vulnerability identified in the Ghost Content Management System. The flaw resides in the server-side image fetching mechanism of the ImageSize class, which allows authenticated, staff-level users to force the backend to perform unvalidated HTTP GET requests targeting local or private network services. This report provides an in-depth exploration of the root cause, vulnerable code structures, patch implementations, and mitigation steps.
The Ghost Content Management System includes administrative interfaces for managing content, publications, and layouts. Within these panels, administrators and staff-level users frequently upload images, link to external assets, or provide bookmark URLs that require automated generation of metadata. When a URL is submitted, the application core retrieves the file to parse metadata and establish physical dimensions (width and height). This architectural design introduces an attack surface where the application host acts as an HTTP client on behalf of authenticated operators.
The core issue arises when processing image formats that cannot be dynamically streamed to determine dimension headers, such as SVG files or other vector formats designated in the FETCH_ONLY_FORMATS collection. In these cases, the backend must retrieve the entire payload into local application memory before evaluating its contents. Historically, this retrieval operation was routed through a generalized HTTP request wrapper that lacked destination restrictions, validating neither DNS resolutions nor target IP addresses.
As a result, an authenticated user possessing staff-level privileges can supply internal URLs pointing to loopback addresses, local network resources, or cloud metadata endpoints. Because the underlying connection client performs no egress validation, the application host initiates a TCP handshake and HTTP GET transaction against the specified internal destination. This behavior classifies the vulnerability as a Server-Side Request Forgery (SSRF), registered as CWE-918, which compromises the isolation of internal network perimeters.
The root cause of CVE-2026-70591 resides within the ImageSize class constructor and helper methods located in ghost/core/core/server/lib/image/image-size.js. Specifically, the class initialized a request agent reference (this.request) using a generic HTTP client wrapper passed down through dependency injection. When resolving image dimensions from an external URL, the _fetchImageSizeFromUrl function initiated a request using this unvalidated agent, executing this.request(imageUrl, this.REQUEST_OPTIONS).
This generic request wrapper executed default DNS resolution and standard TCP connection setup without validation routines. It did not verify whether the resolved IP address belonged to private IP address ranges defined by RFC 1918 (such as 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16), loopback adapters (127.0.0.1/8 or ::1), or link-local endpoints (169.254.169.254). Without an application-level blocklist or DNS interception agent, the host operating system's default network routing was utilized directly.
To trigger the vulnerability, an attacker must influence the parameter passed to _fetchImageSizeFromUrl by executing administrative tasks. These tasks include inserting a remote bookmark card, embedding an external image link, or updating publication icons via the administration panel. Once the application receives the target URL, the routing logic identifies that the target format requires a full content download, bypasses stream-based size checking (such as the probe library), and invokes the vulnerable full-payload request.
To resolve the SSRF exposure, the Ghost maintenance team modified the dependency injection model of the image utilities framework. In commit 5eff2de0f477b11c88f20bceb9d184c0d3b8a62e, the generic request parameter in the ImageSize constructor was replaced with a secure utility function called fetchExternal. This function relies on Ghost's pre-configured externalRequest client to enforce strict destination validation rules.
Below is the analysis of the patch applied to the core image handling code. Notice that the unsecured this.request parameter is removed entirely from ImageSize, preventing legacy insecure requests from executing.
// ghost/core/core/server/lib/image/image-utils.js (Patched Version)
// This function wraps externalRequest, injecting SSRF protection via the underlying 'got' configuration.
function fetchExternal(url, options = {}) {
return externalRequest.get(url, {
headers: options.headers,
timeout: {
request: options.response_timeout || 10000
},
responseType: 'buffer',
retry: {limit: 0}
});
}The implementation of externalRequest provides mitigation against SSRF by configuring DNS resolution hooks. Before a connection is established, the module resolves the target host's IP address and validates it against a restricted list of subnets. If the address matches a private or loopback range, the connection is blocked at the application layer, preventing the server from emitting the HTTP GET request. The patch updates ImageSize to consume fetchExternal as illustrated below:
// ghost/core/core/server/lib/image/image-size.js (Patched Version)
class ImageSize {
constructor({config, imageStore, storageUtils, validator, urlUtils, fetchExternal, probe}) {
this.config = config;
this.imageStore = imageStore;
this.storageUtils = storageUtils;
this.validator = validator;
this.urlUtils = urlUtils;
this.fetchExternal = fetchExternal; // Secure client injected
this.probe = probe;
// ...
}
_fetchImageSizeFromUrl(imageUrl) {
// Replaced this.request with this.fetchExternal
return this.fetchExternal(imageUrl, this.NEEDLE_OPTIONS).then((response) => {
return this._imageSizeFromBuffer(response.body);
});
}
}Exploitation of CVE-2026-70591 requires administrative credentials possessing at least staff-level privileges on the target Ghost installation. An attacker cannot execute this attack unauthenticated because the vulnerable image dimensions parser is only accessible through endpoints mapped to the authenticated Ghost Admin session. Once authenticated, the attacker identifies inputs designed to fetch and process remote assets.
An attacker crafts a payload targeting an internal port, such as an administrative console running on localhost or a cloud metadata service endpoint. For example, the attacker can submit http://169.254.169.254/latest/meta-data/ to compromise hosting platform configurations. Upon receiving the input, the Ghost backend triggers the ImageSize resolution pathway, causing the application host to perform a DNS resolution and initiate an HTTP transaction.
While the server does not output the raw response content to the user's browser, the exploitation constitutes a blind SSRF. An attacker can map local network architecture by analyzing differences in application response times and error structures. Fast connection refusals or socket errors indicate closed ports, whereas prolonged timeouts or specific HTTP error codes (such as protocol mismatch notifications) indicate that a port is open and actively running an internal service.
The impact of this Server-Side Request Forgery vulnerability is classified as moderate, with a CVSS v3.1 score of 4.1. Because the attack requires active staff credentials, the threat model assumes an attacker has already bypassed the external authentication barrier or is an inside threat. Despite this prerequisite, the ability to pivot network requests from an external application context to internal network zones remains a significant risk.
The primary risk associated with this vulnerability is internal network reconnaissance. Attackers can execute port scans against local hosting systems or neighboring container networks that are isolated by firewall rules. This capability can reveal running services, management APIs (e.g., Consul, Kubernetes Kubelet API), and other unauthenticated microservices that rely strictly on network perimeter isolation for security.
Furthermore, when Ghost is deployed on cloud infrastructure (such as AWS, Google Cloud, or Azure), the SSRF can target the instance metadata service (IMDS). If IMDSv1 is enabled without session token enforcement, the attacker can leverage the blind SSRF to retrieve sensitive platform configurations, temporary IAM credentials, and instance identifiers, escalating their access from a CMS staff account to full control of the cloud environment.
Remediation of CVE-2026-70591 requires updating the Ghost deployment to version 6.54.1 or subsequent stable releases. The patch implements secure dependency injection by replacing the unvalidated request agent with fetchExternal. This change guarantees that all outgoing full-payload image requests are subjected to the pre-established SSRF validation policies enforced by the platform's standard external request client.
If immediate patching to 6.54.1 is not possible, administrators must implement network-level mitigations to restrict outgoing traffic from the application host. Outbound egress filtering rules should be configured via iptables or cloud security groups. These rules must block outbound requests from the Ghost process targeting local network interfaces, RFC 1918 addresses, and the link-local metadata address 169.254.169.254, except for authorized external connections.
Security teams should also conduct an audit of active user accounts in the Ghost Admin panel. Revoke inactive staff credentials and enforce strong multi-factor authentication (MFA) to minimize the risk of credential compromise. Additionally, enable IMDSv2 (Session Tokens) on AWS-hosted instances to block metadata exfiltration through SSRF techniques.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Ghost TryGhost | >= 0.10.0, < 6.54.1 | 6.54.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network (AV:N) |
| CVSS Score | 4.1 (Medium) |
| Exploit Status | PoC / Authenticated |
| Impact | Internal Reconnaissance / SSRF |
| KEV Status | Not Listed |
The web server receives a URL or similar vector from an upstream client and retrieves the resource without validating the destination, allowing requests to reach internal networks.
An origin trust boundary failure in the Ruby mechanize library (prior to v2.14.1) allows unauthenticated remote web servers to harvest sensitive global request headers, such as Authorization Bearer tokens and cookies, by utilizing HTML-level meta-refresh redirection tags. Standard HTTP-level redirect boundaries were not applied to document-level redirects, creating a vector for cross-origin credential leakage during automated crawls.
CVE-2026-107718 is a medium-severity Open Redirect vulnerability in the core HTTP server package of the AdonisJS Node.js framework. Prior to versions 8.2.3 and 9.3.0, the framework built route paths by directly interpolating dynamic parameters and wildcard segments without URI encoding. If an application routes attacker-controlled input directly to a dynamic first path segment and uses the generated route URL as a redirect destination, a leading slash can produce a scheme-relative external URL. Modern web browsers process scheme-relative URLs by redirecting the client to the specified external domain, exposing users to credential harvesting, social engineering, and session hijacking. This vulnerability affects all applications running unpatched configurations where input validation is not explicitly implemented before generating paths.
CVE-2026-107725 is a critical security bypass in Hazelcast where missing authorization checks in the MapPermission class permit unprivileged clients to issue queries containing aggregators or projections. This architectural oversight allows attackers to run arbitrary code on the cluster servers under the privileges of the active Hazelcast process.
A stored Cross-Site Scripting (XSS) vulnerability was identified in Indico, an open-source event management system developed at CERN, prior to version 3.3.13. The vulnerability stems from weak URL validation in custom link fields and lack of HTML sanitization during Marshmallow serialization of event notes. This allows authenticated attackers with event modification privileges to inject malicious payloads that execute in the browser of users viewing the event pages or collaborating on notes.
A technical analysis of CVE-2026-107397, a stored Cross-Site Scripting (XSS) vulnerability in Indico's collaborative notes editor and custom link generation fields. Prior to version 3.3.13, Marshmallow serialization schemas omitted HTML sanitization during conflict resolution, and form validators failed to enforce strict URI schemes, enabling authenticated low-privilege attackers to execute arbitrary JavaScript.
An authorization bypass vulnerability exists in the legacy session export API of Indico, an open-source event management system developed at CERN. Due to a missing object-level access check, authenticated users can bypass configuration-level restrictions to extract private session metadata (including session titles, descriptions, and list of conveners) from events that they are otherwise authorized to view.