Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-13150

CVE-2026-13150: Pentestify SSRF Vulnerability

CVE-2026-13150 is a Server-Side Request Forgery flaw in ccyl13 Pentestify that allows attackers to make the server issue requests to arbitrary URLs. This post covers the technical details, affected versions, and mitigation.

Published:

CVE-2026-13150 Overview

CVE-2026-13150 is a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in ccyl13 Pentestify version 1.0.0 and earlier. The flaw exists in the PDF generation endpoint GET /api/reports/{id}/pdf within backend/main.py. The application builds the rendering target URL from request.base_url without validation. Remote attackers can manipulate the Host header to force the server to issue requests to arbitrary internal or external URLs, including cloud metadata services such as 169.254.169.254. The rendered content is then embedded into the resulting PDF and returned to the attacker.

Critical Impact

Unauthenticated attackers can pivot the server into internal networks and exfiltrate cloud instance metadata, IAM credentials, and other sensitive resources through attacker-controlled Host headers.

Affected Products

  • ccyl13 Pentestify 1.0.0
  • ccyl13 Pentestify versions prior to 1.0.0
  • Fixed in ccyl13 Pentestify 1.1.0

Discovery Timeline

  • 2026-06-24 - CVE-2026-13150 published to NVD
  • 2026-06-24 - Last updated in NVD database

Technical Details for CVE-2026-13150

Vulnerability Analysis

Pentestify exposes a FastAPI endpoint that renders pentesting reports as PDF documents using a headless browser. The endpoint constructs the URL it loads from request.base_url, a value derived from the incoming HTTP Host header. FastAPI trusts this header by default and does not validate it against an allowlist. Because the rendering engine fetches the constructed URL server-side and includes the response in the generated PDF, attackers can redirect that fetch to any reachable host. Cloud workloads are particularly exposed: a request to http://169.254.169.254/latest/meta-data/iam/security-credentials/ returns IAM credentials in the PDF body.

Root Cause

The root cause is unvalidated use of request.base_url when building the internal URL passed to the Playwright renderer. No allowlist, scheme check, or host pinning is applied. Image sources accepted by report schemas were also not constrained to safe formats, expanding the SSRF surface to remote image fetches embedded by report authors.

Attack Vector

An attacker sends an unauthenticated GET /api/reports/{id}/pdf request and supplies a malicious Host header. The server constructs the render target using the attacker-supplied host, then loads that URL with Playwright. The rendered response, including any sensitive data, is written into the returned PDF.

python
# Patch from Pentestify v1.1.0 - backend/main.py
 app = FastAPI(
     title="Pentestify API",
     description="API para gestion de reportes de pentesting",
-    version="1.0.0"
+    version="1.1.0"
 )

 # URL base interna que usa el backend para renderizar PDFs con Playwright.

Source: GitHub Pentestify Commit a058a22

The schema-level fix restricts image sources to base64 data URLs, blocking remote fetches:

python
# Patch from Pentestify v1.1.0 - backend/schemas.py
-from pydantic import BaseModel
+from pydantic import BaseModel, field_validator
 from typing import List, Optional
 from datetime import datetime
+import re
+
+# Logos y evidencias solo pueden ser data URLs de imagen.
+_DATA_IMAGE_RE = re.compile(r'^data:image/[a-zA-Z0-9.+-]+;base64,[A-Za-z0-9+/=\s]+$')
+
+def is_safe_image_src(value) -> bool:
+    return isinstance(value, str) and bool(_DATA_IMAGE_RE.match(value.strip()))
+
+def sanitize_image_list(values, keep_slots: bool = False) -> List[str]:
+    cleaned: List[str] = []
+    for v in (values or []):
+        if v == '' or is_safe_image_src(v):
+            cleaned.append(v)
+        elif keep_slots:
+            cleaned.append('')
+    return cleaned

Source: GitHub Pentestify Commit a058a22

Detection Methods for CVE-2026-13150

Indicators of Compromise

  • Requests to /api/reports/{id}/pdf accompanied by Host headers that do not match the expected Pentestify deployment hostname.
  • Outbound connections from the Pentestify backend to cloud metadata endpoints such as 169.254.169.254 or metadata.google.internal.
  • Generated PDFs containing rendered content that does not originate from internal report templates, such as raw JSON metadata responses.
  • Unexpected egress traffic from the backend to RFC1918 hosts that are not part of normal application flows.

Detection Strategies

  • Inspect FastAPI access logs for Host header values that diverge from approved Pentestify domains and correlate them with PDF endpoint hits.
  • Monitor the report-generation worker for DNS resolution and TCP connections to link-local, loopback, and metadata IP ranges.
  • Hash and compare generated PDFs against expected template output to flag PDFs that embed unexpected remote content.

Monitoring Recommendations

  • Forward web server, FastAPI, and Playwright process logs to a centralized analytics platform and alert on anomalous Host headers.
  • Enable VPC flow log collection on the workload running Pentestify and alert on traffic destined to 169.254.169.254.
  • Track the version string returned by the Pentestify API to ensure deployments are running 1.1.0 or later.

How to Mitigate CVE-2026-13150

Immediate Actions Required

  • Upgrade Pentestify to version 1.1.0 or later, which validates image sources and removes reliance on request.base_url for render targets.
  • Block egress from the Pentestify host to cloud metadata services using host firewall rules or network policies.
  • Restrict access to /api/reports/{id}/pdf behind authenticated, internal-only network segments until the patch is deployed.

Patch Information

The vendor released the fix in commit a058a22b42c6311895622645265df79a60265b1d, bumping the API version from 1.0.0 to 1.1.0. The patch introduces is_safe_image_src and sanitize_image_list validators that accept only base64 image data URLs, eliminating remote fetches during PDF rendering.

Workarounds

  • Place Pentestify behind a reverse proxy that enforces a strict Host header allowlist and rejects requests with unexpected values.
  • Configure the workload's IMDS to require IMDSv2 session tokens, which prevents trivial metadata exfiltration via header-based SSRF.
  • Apply egress filtering so the backend can only reach approved internal services and template asset hosts.
bash
# Example nginx Host header allowlist in front of Pentestify
server {
    listen 443 ssl;
    server_name pentestify.example.com;

    if ($host !~* ^pentestify\.example\.com$) {
        return 421;
    }

    location /api/ {
        proxy_set_header Host pentestify.example.com;
        proxy_pass http://127.0.0.1:8000;
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.