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-XXV7-2VV3-H682

CVE-2026-85650: Server-Side Request Forgery in Trigger.dev Webhook Alert Channel Delivery

Alon Barad
Alon Barad
Software Engineer

Oct 2, 2026·7 min read·5 visits

Executive Summary (TL;DR)

Unvalidated webhook URLs in Trigger.dev allow authenticated users to perform server-side requests against internal services and cloud metadata endpoints.

A critical Server-Side Request Forgery (SSRF) vulnerability in Trigger.dev prior to version 4.5.2 allows authenticated organization members to configure webhook alert channels with unvalidated target URLs. This can lead to internal network scanning and cloud metadata extraction.

Vulnerability Overview

The Trigger.dev control plane web application provides a developer-focused platform to orchestrate background jobs and long-running tasks. To notify administrators of runtime anomalies or task failures, the platform implements alert channels, including HTTP webhooks. When an alert condition is met, the backend system invokes an asynchronous worker to dispatch a notification payload to the configured endpoint.

The vulnerability identified as CVE-2026-85650 (GHSA-xxv7-2vv3-h682) is a Server-Side Request Forgery (SSRF) flaw in this notification delivery mechanism. Versions of the platform prior to 4.5.2 fail to validate or sanitize user-supplied URLs before invoking outbound HTTP requests. Any authenticated user with organization access can register an alert channel pointing to internal resources, exposing the internal environment to unauthorized interaction.

Because the system initiates connections from its own network context, an attacker can leverage the platform as an SSRF proxy. This permits reconnaissance of internal networks, interrogation of local loopback services, and unauthorized access to cloud Instance Metadata Services (IMDS).

Root Cause Analysis

The root cause of CVE-2026-85650 is a multi-layered validation failure within the application database schemas and HTTP client implementation. During alert channel registration, the system does not enforce strict syntactic or structural validation on the destination URL. The Zod schemas responsible for parsing user input only verify that the provided string matches a basic string pattern without imposing domain restrictions or address constraints.

At the database level, the ProjectAlert and associated tables store the unchecked string as a legitimate webhook target. The application relies on global Node.js fetch engines to perform the request execution inside background workers. These worker components execute the HTTP POST requests directly without performing pre-resolution domain checks, address family checks, or private IP filtering.

Additionally, the application lacks connection-bound socket validation, exposing it to DNS rebinding attacks. An attacker can configure a domain that resolves to a public IP during initial inspection but shifts to an internal loopback address during connection initiation. The absence of strict redirection policies further compounds the risk, allowing the client to follow server-instructed redirects to internal subnets.

Code Analysis

In vulnerable versions of Trigger.dev, the database validation schema accepts arbitrary strings for the webhook URL. The model schema apps/webapp/app/models/projectAlert.server.ts uses the z.string() validator rather than enforcing network-safe constraints. This permits loopback and non-routable IP addresses to be successfully stored in the database.

The outbound delivery logic is managed by apps/webapp/app/v3/services/alerts/deliverAlert.server.ts. The worker fetches the URL string directly from the database record and invokes the global fetch API without an isolated agent.

// Vulnerable Implementation
const response = await fetch(webhook.url, {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "x-trigger-signature-hmacsha256": signatureHex,
  },
  body: rawPayload,
  signal: AbortSignal.timeout(5000),
});

To remediate this, the patch introduced in commit 34b1a181c2a1d33a53ebab88f84b05f81fea4254 adds multiple protection layers. The custom safeWebhookFetch service replaces standard fetch, enforcing a socket-level DNS lookup check to reject private IP ranges prior to connection.

// Patched Implementation: Socket-level lookup validation
const safeLookup: LookupFunction = (hostname, options, callback) => {
  dnsPromises
    .lookup(hostname, {
      all: true,
      family: options.family,
      hints: options.hints,
      verbatim: options.verbatim,
    })
    .then((addresses) => {
      try {
        for (const { address, family } of addresses) {
          assertAddressAllowed(address, family);
        } 
      } catch (err) {
        callback(err as NodeJS.ErrnoException, []);
        return;
      }
      if (options.all) {
        callback(null, addresses);
      } else {
        callback(null, addresses[0].address, addresses[0].family);
      }
    })
    .catch((err) => callback(err as NodeJS.ErrnoException, []));
};

Exploitation Methodology

Exploitation of this vulnerability requires authenticated access to a Trigger.dev organization. An attacker with standard membership privileges can register a new alert channel pointing to a protected internal IP or a cloud metadata service endpoint. Because organization registration is open in self-hosted deployments and accessible via compromised tokens in cloud environments, the barrier to entry is minimal.

The attacker sends an HTTP POST request to the alert channels API endpoint, specifying the target internal host within the payload. The user then forces a background task run failure, prompting the backend task orchestrator to generate an alert event. The system identifies the webhook channel, generates a signature, and transmits the payload to the internal server.

Although the response payload is not fully returned to the attacker, the behavior is classified as semi-blind. The attacker can extract system state information by reviewing connection latency, HTTP status codes, and network error logs rendered in the web dashboard. This allows for rapid host discovery and service mapping across the hosting environment.

Impact Assessment

The primary consequence of this vulnerability is the exposure of internal-only network infrastructure to unauthorized authenticated actors. By proxying requests through the Trigger.dev backend, attackers can reach services running on the loopback interface (127.0.0.1) that are not exposed to the public internet. This includes local administration portals, database management ports, and internal microservice APIs.

In cloud-hosted deployments, the threat extends to the Instance Metadata Service (IMDS). An attacker targeting http://169.254.169.254/latest/meta-data/ can obtain cloud credentials, IAM roles, and configuration parameters assigned to the webapp container. This can lead to lateral movement and full cloud account compromise depending on the permissions granted to the application host.

The CVSS v3.1 base score is rated at 7.7 (High) reflecting the scope change (S:C) associated with traversing the security boundary from the public application web server to internal cloud infrastructure. The vulnerability is categorized under CWE-918 (Server-Side Request Forgery) and maps to MITRE ATT&CK techniques T1190 (Exploit Public-Facing Application) and T1005 (Data from Local System).

Remediation Analysis

Remediation of CVE-2026-85650 requires upgrading self-hosted instances of Trigger.dev to version 4.5.2 or above. The official patch implements a comprehensive defensive framework that blocks private IP ranges and addresses DNS rebinding. This is achieved by binding IP validation directly to the connection lookup phase rather than relying on pre-resolve hooks.

// IP verification logic implemented in safeWebhookUrl.server.ts
function isUnsafeIPv4(host: string): boolean {
  const parts = host.split(".");
  if (parts.length !== 4) return false;
  const nums = parts.map((p) => Number(p));
  if (nums.some((n) => !Number.isInteger(n) || n < 0 || n > 255)) return false;
  const [a, b] = nums;
  if (a === 0) return true; // unspecified
  if (a === 127) return true; // loopback
  if (a === 10) return true; // RFC 1918 Private
  if (a === 172 && b >= 16 && b <= 31) return true; // RFC 1918 Private
  if (a === 192 && b === 168) return true; // RFC 1918 Private
  if (a === 169 && b === 254) return true; // link-local (IMDS)
  if (a === 100 && b >= 64 && b <= 127) return true; // carrier-grade NAT
  if (a >= 224 && a <= 239) return true; // multicast
  if (a >= 240) return true; // reserved
  return false;
}

For environments where immediate patching is not possible, network-level egress filtering must be enforced. Administrators should apply firewall rules or security groups restricting outbound traffic from the application web workers to internal subnets. Cloud environments must enforce IMDSv2 and restrict hop limits to mitigate the risk of metadata extraction.

Regular security audits should include querying the database for existing non-public webhook registrations. Organizations running self-hosted deployments can run automated scripts to inspect active webhook targets and confirm compliance with internal security policies.

Official Patches

Trigger.devPull Request #4199 fixing SSRF in alert channel delivery

Fix Analysis (1)

Technical Appendix

CVSS Score
7.7/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
EPSS Probability
0.35%
Top 74% most exploited

Affected Systems

Trigger.dev Control Plane WebappTrigger.dev Self-Hosted Web Application

Affected Versions Detail

Product
Affected Versions
Fixed Version
trigger.dev
Trigger.dev
< 4.5.24.5.2
AttributeDetail
CWE IDCWE-918 (Server-Side Request Forgery)
Attack VectorNetwork (AV:N)
CVSS v3.1 Base Score7.7 (High)
EPSS Score0.00348
Exploit StatusPoC (Proof of Concept Available)
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1005Data from Local System
Collection
CWE-918
Server-Side Request Forgery (SSRF)

The web application receives a user-specified URL and sends a request to it without fully validating the destination.

Known Exploits & Detection

GitHub Security AdvisoryExploit methodology and remediation report for the webhook delivery SSRF.

References & Sources

  • [1]GitHub Advisory GHSA-xxv7-2vv3-h682
  • [2]Official Patch Commit
  • [3]Trigger.dev Release v4.5.2
  • [4]Authoritative CVE Record

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.

More Reports

•about 4 hours ago•GHSA-C9XM-49CP-XCR9
6.3

GHSA-C9XM-49CP-XCR9: Server-Side Request Forgery in rmcp OAuth Client

A Server-Side Request Forgery (SSRF) vulnerability exists in the rmcp OAuth client, which is part of the Model Context Protocol (MCP) Rust SDK. The vulnerability arises from insecure processing of the resource_metadata parameter in WWW-Authenticate headers returned by a malicious or compromised MCP server. The client parses and fetches absolute URLs from this header without validation of scheme, origin, or network routing, allowing remote attackers to initiate HTTP GET requests to local network interfaces, RFC 1918 private subnets, or cloud metadata endpoints.

Alon Barad
Alon Barad
5 views•6 min read
•about 9 hours ago•CVE-2026-92945
4.2

CVE-2026-92945: Sandbox Escape and Module Allowlist Bypass via Path Prefix Matching in vm2

A module allowlist bypass vulnerability (CVE-2026-92945 / GHSA-7q3f-wx44-378m) was identified in the vm2 sandboxing library prior to version 3.11.7. This flaw permits unauthenticated or untrusted code running within the sandbox environment to bypass explicit module restrictions. When the transitive resolution option is disabled, the system fails to validate file system path boundaries, allowing prefix-sharing sibling directories to be resolved and loaded, thereby escaping intended sandbox restrictions.

Amit Schendel
Amit Schendel
6 views•6 min read
•about 10 hours ago•CVE-2026-92941
10.0

CVE-2026-92941: Sandbox Escape and Process-Wide TLS Trust Store Manipulation in vm2

CVE-2026-92941 is a critical sandbox-escape and trust-manipulation vulnerability in the vm2 library (versions 3.11.3 to 3.11.6). This security flaw allows untrusted code executing within a NodeVM sandbox environment to compromise the global TLS trust store of the host Node.js process. By leveraging a design flaw where the host's native 'tls.setDefaultCACertificates' can be executed via a proxy wrapper, combined with a bridge unwrapping bypass in the 'url' module, an attacker can modify the process-wide default root Certificate Authorities. Consequently, all subsequent outbound TLS/HTTPS clients running on the host thread are forced to trust attacker-signed certificates, facilitating transparent Man-in-the-Middle (MitM) attacks. The vulnerability was resolved in version 3.11.7 of vm2 by introducing built-in member-level sanitization before applying read-only proxy wrappers.

Amit Schendel
Amit Schendel
5 views•10 min read
•about 11 hours ago•CVE-2026-92944
9.8

CVE-2026-92944: Sandbox Escape in vm2 via Stale V8 PromiseThenLookupChain Protector

A critical engine-level reachability failure in Node.js 26 running V8 14.6 allows attackers to escape the vm2 sandbox environment. When consecutive prototype properties are modified using sequential assignments, a V8 optimization bug fails to invalidate the PromiseThenLookupChain protector. By calling Promise.prototype.finally, the attacker bypasses the vm2 wrappers, hijacks the promise reaction using a custom constructor, triggers a calibrated stack overflow to capture a host-realm RangeError, and executes arbitrary shell commands on the host.

Alon Barad
Alon Barad
7 views•8 min read
•about 12 hours ago•CVE-2026-92939
9.9

CVE-2026-92939: Critical Sandbox Escape via Host Crypto setEngine Native Code Execution in vm2

A critical sandbox escape vulnerability in the vm2 library allows sandboxed JavaScript code to bypass containment and execute arbitrary native code on the host process. This occurs when the host's builtin crypto module is exposed to the NodeVM environment. Although vm2 implements a read-only proxy layer to restrict direct modifications to host properties, it does not prevent invocation of host-level functions. By calling the crypto.setEngine API with a path to a malicious native library on disk, an attacker can trigger OpenSSL's dynamic module loader. The host's operating system loader immediately runs the dynamic library's initializers/constructors before verifying engine compatibility, leading to remote code execution in the context of the host process.

Amit Schendel
Amit Schendel
6 views•5 min read
•about 13 hours ago•CVE-2026-92938
9.9

CVE-2026-92938: Remote Code Execution in vm2 via node:sqlite DatabaseSync Sandbox Escape

CVE-2026-92938 is a critical sandbox escape vulnerability in the vm2 library (versions 3.11.3 through 3.11.6) that allows arbitrary native code execution on the host when the node:sqlite built-in module is loaded inside a sandboxed NodeVM environment.

Amit Schendel
Amit Schendel
9 views•8 min read