CVE-2026-76795 Overview
CVE-2026-76795 is a Server-Side Request Forgery (SSRF) vulnerability in AeternaLabsHQ PullMD version 3.2.0. The flaw resides in the /api REST endpoint, where the url argument is passed to a fetch routine without validating the destination address. An unauthenticated remote attacker can coerce the PullMD server into issuing HTTP requests to internal services, loopback interfaces, link-local addresses, and cloud-metadata endpoints. The issue is tracked under CWE-918: Server-Side Request Forgery and has been publicly disclosed. Upgrading to PullMD 3.3.0 resolves the vulnerability by enforcing an allowlist model for outbound URL fetches.
Critical Impact
Unauthenticated remote attackers can force PullMD to fetch attacker-chosen URLs, exposing internal HTTP services and cloud instance metadata endpoints.
Affected Products
- AeternaLabsHQ PullMD 3.2.0
- REST API endpoint /api (parameter url)
- Fixed in PullMD 3.3.0
Discovery Timeline
- 2026-08-20 - CVE-2026-76795 published to NVD
- 2026-08-20 - Last updated in NVD database
- Patch commit 96448894cc93ccecb0bdcbf263a9d25390a8455e merged via pull request #42 and released in PullMD v3.3.0
Technical Details for CVE-2026-76795
Vulnerability Analysis
PullMD exposes a REST API endpoint at /api that accepts a user-supplied url argument and fetches the referenced content server-side. In version 3.2.0, the handler performs no filtering on the destination host or IP address. Any HTTP client on the network can submit a request whose url parameter targets internal-only resources.
Because the request originates from the PullMD server, it bypasses network segmentation controls that would normally block external clients. Attackers can reach services bound to 127.0.0.1, RFC1918 ranges such as 10.0.0.0/8, link-local addresses like 169.254.169.254, and Carrier-Grade NAT (CGNAT) space. Cloud-metadata endpoints on AWS, Azure, and GCP are of particular concern because they can expose temporary IAM credentials.
Root Cause
The root cause is missing destination validation in the URL-fetch pipeline within lib/mcp.js. The fetch helper trusted any parsed URL that resolved successfully. There was no CIDR-based deny list, no DNS re-resolution guard, and no allowlist mechanism for legitimate internal targets. This aligns directly with CWE-918.
Attack Vector
The vulnerability is exploitable over the network without authentication or user interaction. An attacker submits a crafted request to /api supplying an internal address in the url field. The server issues the outbound request and returns response data or timing signals to the attacker, enabling internal service discovery and metadata credential theft.
// Patch excerpt from lib/mcp.js in commit 96448894cc93ccecb0bdcbf263a9d25390a8455e
import { z } from 'zod';
import { mergeFrontmatter, mergeMediaFrontmatter } from './frontmatter.js';
import { publicUrlFor, PULLMD_VERSION } from './distrib.js';
+import { assertUrlAllowed, SsrfError } from './ssrf.js';
function shareUrl(publicUrl, shareId) {
if (!shareId) return null;
Source: GitHub commit 96448894. The patch introduces assertUrlAllowed and an SsrfError type to reject requests targeting private, loopback, link-local, CGNAT, or cloud-metadata address ranges before the fetch is issued.
Detection Methods for CVE-2026-76795
Indicators of Compromise
- Outbound HTTP requests from the PullMD process to 169.254.169.254, metadata.google.internal, or 100.100.100.200 (Alibaba metadata).
- Requests to /api where the url parameter contains RFC1918 addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) or 127.0.0.0/8.
- Unusual DNS lookups from the PullMD host resolving to internal-only hostnames.
- Repeated /api calls from a single source iterating through IP ranges or common internal ports.
Detection Strategies
- Inspect application access logs for the /api endpoint and parse the url argument against a deny list of private, loopback, link-local, and metadata ranges.
- Enforce egress logging on the PullMD host and correlate outbound connections with inbound /api calls to identify SSRF pivots.
- Alert on any HTTP request from the PullMD service to cloud-provider metadata IPs, which should never occur under normal operation.
Monitoring Recommendations
- Deploy egress firewall rules that deny PullMD host traffic to internal ranges and metadata endpoints, and alert on drops.
- Continuously monitor for PullMD versions older than 3.3.0 in software inventory to identify unpatched deployments.
- Track authentication logs on internal services that PullMD could reach, looking for unexpected requests originating from the PullMD host IP.
How to Mitigate CVE-2026-76795
Immediate Actions Required
- Upgrade PullMD to version 3.3.0 or later, which includes the SSRF protection patch from commit 96448894cc93ccecb0bdcbf263a9d25390a8455e.
- Restrict outbound network egress from the PullMD host to only the destinations required for legitimate URL-fetch operations.
- Rotate any cloud IAM credentials tied to the instance role if PullMD 3.2.0 was exposed to untrusted networks.
Patch Information
The fix is available in PullMD v3.3.0. It adds a new assertUrlAllowed guard in lib/ssrf.js and blocks private, loopback, link-local, CGNAT, and cloud-metadata addresses by default. Administrators can opt-in to specific internal hosts via the PULLMD_ALLOWED_HOSTS environment variable. Full details are documented in pull request #42 and issue #41.
Workarounds
- Place PullMD behind an egress proxy that enforces a strict allowlist of external destinations for the /api endpoint.
- Block network access from the PullMD host to 169.254.169.254 and all RFC1918 ranges at the host firewall until the upgrade is applied.
- Require authentication in front of the /api endpoint via a reverse proxy to reduce the unauthenticated attack surface.
# Example .env.example configuration introduced in PullMD 3.3.0
# SSRF protection: by default all private, loopback, link-local, CGNAT and
# cloud-metadata IP ranges are blocked for the URL-fetch endpoints.
# To allow a specific internal host or range, list it as CIDRs and/or hostnames.
# Empty = block all internal.
# Example:
PULLMD_ALLOWED_HOSTS=10.0.5.0/24,wiki.internal
Source: GitHub commit 96448894.
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

