CVE-2026-70591 Overview
CVE-2026-70591 is a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in Ghost, a Node.js content management system. The flaw affects Ghost versions from 0.10.0 up to 6.54.1. The Admin image fetching functionality allowed any staff-level user to issue blind HTTP GET requests against internal hosts. While the response body was not returned to the attacker, timing and error signals could reveal open ports on internal infrastructure. The issue is fixed in Ghost version 6.54.1.
Critical Impact
Authenticated staff users can probe internal network services reachable from the Ghost server, exposing infrastructure that should not be accessible from the public content management interface.
Affected Products
- Ghost CMS versions 0.10.0 through 6.54.0
- Ghost Admin image fetching component (ghost/core/core/server/lib/image/)
- Self-hosted Ghost deployments on Node.js
Discovery Timeline
- 2026-08-04 - CVE-2026-70591 published to NVD
- 2026-08-05 - Last updated in NVD database
Technical Details for CVE-2026-70591
Vulnerability Analysis
The vulnerability resides in the Ghost Admin image fetching pipeline. When Ghost retrieved image metadata from an external URL supplied by a staff-level user, it used a got HTTP client instance that did not enforce SSRF protections consistently across all image types. This inconsistency allowed a staff user to submit URLs pointing to internal hosts such as 127.0.0.1, 169.254.169.254, or private RFC 1918 addresses. The server dispatched HTTP GET requests to those targets on behalf of the attacker. Although no response body was returned to the client, differing response times and error conditions leaked whether ports were open or closed, enabling blind internal network reconnaissance.
Root Cause
The ImageSize class in ghost/core/core/server/lib/image/image-size.js constructed a generic got request client using this.request without routing outbound calls through the hardened externalRequest wrapper that enforces host allowlists and blocks private IP ranges. Some image code paths used the safe client while others did not, creating an inconsistent security boundary.
Attack Vector
Exploitation requires authenticated access at the staff privilege level, reflected by the high privileges required in the CVSS vector. An attacker submits an image URL through the Ghost Admin interface referencing an internal host and port. The server issues a blind GET request. Observable side channels such as request latency, HTTP error codes, or connection failures enable port scanning of the internal network from the Ghost host's perspective.
// Security patch in ghost/core/core/server/lib/image/image-size.js
class ImageSize {
- constructor({config, imageStore, storageUtils, validator, urlUtils, request, probe}) {
+ constructor({config, imageStore, storageUtils, validator, urlUtils, fetchExternal, probe}) {
this.config = config;
this.imageStore = imageStore;
this.storageUtils = storageUtils;
this.validator = validator;
this.urlUtils = urlUtils;
- this.request = request;
+ this.fetchExternal = fetchExternal;
this.probe = probe;
- this.REQUEST_OPTIONS = {
- headers: {
- 'User-Agent': 'Mozilla/5.0 Safari/537.36'
- },
- timeout: {
- request: this.config.get('times:getImageSizeTimeoutInMS') || 10000
- },
- retry: {
- limit: 0
- },
- responseType: 'buffer'
- };
// Source: https://github.com/TryGhost/Ghost/commit/5eff2de0f477b11c88f20bceb9d184c0d3b8a62e
The patch replaces the unprotected request client with a fetchExternal helper that routes calls through the externalRequestgot client, which enforces SSRF protections:
// Fix in ghost/core/core/server/lib/image/image-utils.js
+// For image formats that require a full fetch. This function ensures that
+// SSRF protections are in place by using the externalRequest `got` client.
+function fetchExternal(url, options = {}) {
+ return externalRequest.get(url, {
+ headers: options.headers,
+ timeout: {
+ request: options.response_timeout || 10000
+ },
+ responseType: 'buffer',
+ retry: {limit: 0}
+ });
+}
// Source: https://github.com/TryGhost/Ghost/commit/5eff2de0f477b11c88f20bceb9d184c0d3b8a62e
Detection Methods for CVE-2026-70591
Indicators of Compromise
- Outbound HTTP GET requests originating from the Ghost server to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8) or link-local addresses (169.254.0.0/16).
- Repeated image upload or URL submission events in Ghost Admin logs by the same staff user against varying hostnames or ports.
- Ghost server error logs showing connection timeouts or refused connections to internal endpoints during image size lookups.
Detection Strategies
- Audit Ghost Admin activity logs for POST requests to image-related endpoints that include URLs pointing to non-public destinations.
- Correlate egress firewall logs with Ghost application logs to identify image fetch requests targeting internal infrastructure.
- Alert on any Node.js process associated with Ghost initiating TCP connections to metadata service addresses such as 169.254.169.254.
Monitoring Recommendations
- Enable verbose logging in the Ghost image-size and image-utils modules to record the destination URL of every external fetch.
- Configure network egress policies that only allow the Ghost host to reach known content delivery networks and image origins.
- Track staff-account creation and image submission patterns for anomalies, particularly bursts of failed image lookups.
How to Mitigate CVE-2026-70591
Immediate Actions Required
- Upgrade Ghost to version 6.54.1 or later, which routes image fetches through the SSRF-hardened externalRequest client.
- Review the staff-user roster and remove accounts that no longer require Admin access.
- Inspect application and egress logs for prior internal probing activity by staff-level accounts.
Patch Information
The vulnerability is fixed in Ghost 6.54.1. Refer to the GitHub Release v6.54.1, the GitHub Security Advisory GHSA-gcvv-72q8-9v76, and the remediation commit for full technical detail.
Workarounds
- Restrict outbound network access from the Ghost server using host or network firewall rules that deny traffic to RFC 1918 and link-local ranges.
- Place Ghost behind an egress proxy that whitelists approved image origins only.
- Limit staff-level account provisioning until the upgrade to 6.54.1 is completed.
# Example egress restriction using iptables on the Ghost host
iptables -A OUTPUT -m owner --uid-owner ghost -d 127.0.0.0/8 -j REJECT
iptables -A OUTPUT -m owner --uid-owner ghost -d 10.0.0.0/8 -j REJECT
iptables -A OUTPUT -m owner --uid-owner ghost -d 172.16.0.0/12 -j REJECT
iptables -A OUTPUT -m owner --uid-owner ghost -d 192.168.0.0/16 -j REJECT
iptables -A OUTPUT -m owner --uid-owner ghost -d 169.254.0.0/16 -j REJECT
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

