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



GHSA-89V5-38XR-9M4J
Not Assigned

GHSA-89V5-38XR-9M4J: Multiple Server-Side Request Forgery (SSRF) Vectors in Postiz

Alon Barad
Alon Barad
Software Engineer

Mar 27, 2026·6 min read·1 visit

PoC Available

Executive Summary (TL;DR)

Multiple endpoints in Postiz (< v2.21.2) fail to validate user-supplied URLs, enabling unauthenticated attackers to perform SSRF attacks against internal infrastructure and cloud metadata services. The implemented patch provides a basic blocklist but leaves the application vulnerable to DNS rebinding bypasses.

Postiz versions prior to v2.21.2 are vulnerable to Server-Side Request Forgery (SSRF) due to insufficient validation of user-supplied URLs across multiple application components. Attackers can exploit these flaws in the webhook management, RSS feed parsing, and HTML loading endpoints to force the server into making arbitrary network requests. This allows unauthorized access to internal network resources, local services, and cloud environment metadata.

Vulnerability Overview

The Postiz application, prior to version 2.21.2, contains multiple Server-Side Request Forgery (SSRF) vulnerabilities classified under CWE-918. The application exposes endpoints that accept uniform resource identifiers (URIs) from users and subsequently issues HTTP requests to those designated addresses. These endpoints are located within the webhook management system, the RSS feed parsing functionality, and the HTML URL loading modules.

The core of the vulnerability lies in the application acting as an unrestricted proxy. The underlying Node.js backend utilizes HTTP client libraries such as fetch, rss-parser, and JSDOM to process these user-supplied URIs. The application initiates outbound connections without verifying the safety or network location of the target destination.

This behavior exposes the internal network perimeter to external threat actors. Attackers can manipulate the url query parameters or stored webhook configurations to target adjacent systems that are normally inaccessible from the public internet. The lack of ingress validation or egress filtering ensures these requests succeed with the privileges of the Postiz application host.

Root Cause Analysis

The primary root cause is the direct consumption of untrusted input by server-side network components without applying destination validation. In the apps/backend/src/api/routes/webhooks.controller.ts file, the sendWebhook endpoint extracts a url parameter from the incoming HTTP request. The application immediately passes this raw parameter to the native fetch() API without any sanity checks.

A similar structural flaw exists within the libraries/nestjs-libraries/src/database/prisma/autopost/autopost.service.ts component. The RSS feed and HTML loader modules invoke rss-parser and JSDOM respectively, using URLs derived from user configurations or direct query parameters. Furthermore, stored webhooks handled by apps/orchestrator/src/activities/post.activity.ts process outbound payloads with identical unrestricted network access.

Prior to the patch, the application lacked protocol restrictions, hostname validation, and IP address verification. The server resolved whatever domain was provided and initiated a TCP connection regardless of whether the resolved address resided in a private, loopback, or cloud-reserved CIDR block.

Code Analysis and Patch Review

The remediation introduced in commits 0ad89ccd26b1c387c4f3f3544b18c20d33586466 and be5d871896e97cb1f5a2c9241f156b6a1e1debe8 implements a custom NestJS validation decorator named @IsSafeWebhookUrl. This decorator attempts to enforce strict constraints on all user-supplied URIs before they reach the vulnerable sink. The patch enforces the https: protocol and explicitly checks the hostname string to block the literal value localhost.

The core of the fix relies on the IsSafeWebhookUrlConstraint class to perform IP-level blocklisting. The validator calls dns.lookup to resolve the provided hostname into an array of associated IP addresses. The code then iterates through these addresses to verify they do not fall within restricted subnets.

The blocklist logic filters out common internal network segments. Restricted IPv4 ranges include 0.0.0.0/8, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, and 192.168.0.0/16. Restricted IPv6 ranges cover loopback (::1), link-local (fe80::/10), and unique local (fc00::/7) addresses.

// Example of the patched validation flow structure
async validate(url: string) {
  const parsedUrl = new URL(url);
  if (parsedUrl.protocol !== 'https:') return false;
  if (parsedUrl.hostname === 'localhost') return false;
  
  // DNS Resolution
  const records = await dns.promises.lookup(parsedUrl.hostname, { all: true });
  for (const record of records) {
    if (isRestrictedIP(record.address)) {
      return false; // Blocks internal IPs
    }
  }
  return true;
}

Exploitation Methodology

An attacker exploits this vulnerability by constructing HTTP requests targeting the vulnerable endpoints with specific internal URIs. The objective is to manipulate the url parameter so the Postiz server issues a secondary request to a designated internal target. The attacker does not need prior authentication if the webhook or autopost endpoints are publicly accessible.

To map the internal network or probe local services, the attacker submits payloads targeting loopback or private IP addresses. For example, a request to https://postiz-instance.com/webhooks/send?url=http://127.0.0.1:6379 forces the server to connect to its local Redis instance. The attacker analyzes the server's response times, error codes, or reflected data to confirm the service's existence and operational status.

In environments hosted on public cloud infrastructure (AWS, GCP, Azure), the attacker targets the cloud metadata service. By supplying the payload http://169.254.169.254/latest/meta-data/ to the autopost/send endpoint, the attacker forces the server to retrieve environment variables and Identity and Access Management (IAM) credentials. These credentials are subsequently reflected back to the attacker or used to escalate privileges outside the application scope.

Residual Risk and Bypass Analysis

While the @IsSafeWebhookUrl validator effectively prevents trivial exploitation using static private IP addresses, it introduces a Time-of-Check to Time-of-Use (TOCTOU) vulnerability. This architectural flaw leaves the application susceptible to DNS Rebinding attacks. The vulnerability persists because the validation logic and the execution logic perform distinct, decoupled DNS resolutions.

During the validation phase, IsSafeWebhookUrlConstraint executes dns.lookup to retrieve the IP address and checks it against the blocklist. An attacker controls a custom DNS server and configures it to return a safe, public IP address (e.g., 8.8.8.8) with an extremely low Time-To-Live (TTL). The validation phase succeeds because the public IP is not restricted.

Immediately after validation, the application passes the URL to the fetch() API. Because the initial DNS record has expired, the Node.js runtime performs a second DNS resolution. The attacker's DNS server now responds with a restricted private IP address (e.g., 169.254.169.254). The fetch() client connects to the internal service, successfully bypassing the application-layer blocklist entirely.

A comprehensive remediation requires eliminating the TOCTOU window. The application must utilize a customized HTTP agent that performs socket-level validation. Libraries such as request-filtering-agent ensure the IP address is validated after the final DNS resolution and pinned directly to the connection socket, preventing rebinding behavior.

Impact Assessment

Successful exploitation of this Server-Side Request Forgery vulnerability fundamentally compromises the network perimeter. The Postiz server functions as an unauthenticated gateway, allowing external attackers to interact with services hosted on the internal management network. This invalidates network segmentation and firewall controls intended to protect internal infrastructure.

The compromise of cloud metadata services yields a critical impact on confidentiality and integrity. The retrieval of temporary cloud credentials allows the attacker to assume the identity of the underlying virtual machine or container. This access enables the attacker to interact directly with cloud APIs, read cloud storage buckets, and potentially modify infrastructure configurations.

Accessing internal databases or caching servers (such as Redis) exposes backend data structures. Depending on the target service's configuration, attackers can read sensitive application data, manipulate session states, or inject malicious payloads into backend storage. This facilitates lateral movement and secondary exploitation vectors targeting internal administration systems.

Official Patches

gitroomhqOfficial Release Page for v2.21.2

Fix Analysis (2)

Technical Appendix

CVSS Score
Not Assigned/ 10

Affected Systems

Postiz Webhooks ControllerPostiz Autopost ServicePostiz Orchestrator Activity

Affected Versions Detail

Product
Affected Versions
Fixed Version
postiz-app
gitroomhq
< 2.21.2v2.21.2
AttributeDetail
Vulnerability TypeServer-Side Request Forgery (SSRF)
CWE IDCWE-918
Attack VectorNetwork
Authentication RequiredNone
Exploit StatusProof of Concept (PoC) Available
Primary ImpactUnauthorized Internal Network Access / Credential Disclosure

MITRE ATT&CK Mapping

T1071.001Application Layer Protocol: Web Protocols
Command and Control
T1552.005Cloud Instance Metadata API
Credential Access
CWE-918
Server-Side Request Forgery (SSRF)

The web application receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

Vulnerability Timeline

Patch released in version 2.21.2
2026-03-25
Public Advisory Published on GitHub (Approximate)
2025-07-01

References & Sources

  • [1]GitHub Advisory: GHSA-89V5-38XR-9M4J
  • [2]Fix Commit (Webhooks)
  • [3]Fix Commit (Autopost)
  • [4]Release Page

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.