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

CVE-2026-77066: scanFeedsResolver SSRF Vulnerability

CVE-2026-77066 is a Server-Side Request Forgery flaw in scanFeedsResolver that allows authenticated users to direct servers to request internal endpoints. This article covers technical details, impact, and mitigation.

Updated:

CVE-2026-77066 Overview

CVE-2026-77066 is a Server-Side Request Forgery (SSRF) vulnerability [CWE-918] in Omnivore, an open-source read-later application. The flaw exists in the scanFeedsResolver function within packages/api/src/resolvers/subscriptions/index.ts. The resolver forwards a caller-supplied URL directly to axios.get(url, rssParserConfig()) without any address validation. An authenticated attacker can direct the server to issue HTTP requests to arbitrary internal endpoints and receive parsed feed metadata in response.

Critical Impact

Authenticated users can probe internal network services and extract feed-shaped metadata from reachable endpoints, enabling internal reconnaissance and limited information disclosure.

Affected Products

  • Omnivore API service (packages/api)
  • Omnivore self-hosted deployments prior to commit c4d7d85
  • Omnivore GraphQL scanFeeds query interface

Discovery Timeline

  • 2026-08-20 - CVE-2026-77066 published to NVD
  • 2026-08-20 - Last updated in NVD database

Technical Details for CVE-2026-77066

Vulnerability Analysis

The scanFeedsResolver accepts a URL from an authenticated GraphQL client and passes it directly into axios.get() without host validation. The same source file already implements validateUrl() on the subscribe path, and createPageSaveRequest applies an equivalent check using the private-ip library. That library rejects private and reserved IP ranges. The omission is specific to this resolver, making the flaw a localized defense-in-depth failure rather than a systemic input handling issue.

Root Cause

The root cause is missing URL validation before an outbound HTTP request. The resolver trusts the url argument supplied by the GraphQL caller. Because the server issues the request, requests originate from the API host and can reach loopback addresses, link-local ranges, cloud metadata services, and internal RFC1918 networks that are otherwise unreachable from the internet.

Attack Vector

An authenticated user submits a scanFeeds GraphQL query with a URL targeting internal infrastructure. The resolver parses the response as an RSS or Atom feed, or as HTML, and returns url, title, description, and type fields to the caller. Disclosure is limited to feed-shaped metadata and to <link> elements advertising feeds. Responses that fail to parse still leak reachability information through error differentiation, allowing internal port scanning.

typescript
     }
   }
 
+  // Ensure that we are not running a http request against local/private IPs.
+  try {
+    validateUrl(url)
+  } catch (e) {
+    return {
+      errorCodes: [ScanFeedsErrorCode.BadRequest],
+    }
+  }
+
   try {
-    // fetch page content and parse feeds
     const response = await axios.get(url, rssParserConfig())
     const content = response.data as string
     // check if the content is html or xml

Source: Omnivore security patch commit c4d7d85

Detection Methods for CVE-2026-77066

Indicators of Compromise

  • Outbound HTTP requests from the Omnivore API pod or host targeting RFC1918 ranges, 127.0.0.0/8, or 169.254.169.254
  • GraphQL query logs containing scanFeeds operations with URLs referencing internal hostnames or IP literals
  • Repeated scanFeeds requests from a single authenticated user against varying internal ports
  • Application logs showing axios connection errors correlated with non-public destination addresses

Detection Strategies

  • Inspect API access logs for GraphQL mutations and queries named scanFeeds and correlate the url parameter against an allowlist of external hosts
  • Monitor egress traffic from the Omnivore API service using flow logs or eBPF-based network telemetry
  • Alert on outbound HTTP requests from application service accounts to cloud metadata endpoints such as 169.254.169.254

Monitoring Recommendations

  • Ingest Omnivore API access logs and egress network flows into a centralized data lake for correlation across identity and network telemetry
  • Baseline the destinations that the Omnivore API normally contacts and alert on deviations toward internal subnets
  • Track error-response patterns in scanFeeds responses to identify systematic internal port enumeration

How to Mitigate CVE-2026-77066

Immediate Actions Required

  • Apply upstream commit c4d7d8562e6b9aabb1d8e4dabca268e314baa43a which adds validateUrl() to the scanFeedsResolver and to the webhooksResolver
  • Restrict egress from the Omnivore API service to only the destinations required for feed retrieval
  • Block API-tier access to cloud instance metadata services using IMDSv2 hop-limit enforcement or network policy
  • Review authentication logs for suspicious scanFeeds GraphQL activity from newly registered accounts

Patch Information

The fix is delivered in commit c4d7d8562e6b9aabb1d8e4dabca268e314baa43a in the Omnivore repository. The patch adds a call to validateUrl(url) in packages/api/src/resolvers/subscriptions/index.ts before invoking axios.get(), and imports the same validateUrl function into packages/api/src/resolvers/webhooks/index.ts. The validation relies on the private-ip library to reject private and reserved address ranges. Details are available in the Vulncheck advisory and the Omnivore issue tracker.

Workarounds

  • Place the Omnivore API behind an egress proxy that enforces an allowlist of external feed hosts
  • Deploy Kubernetes NetworkPolicy or host firewall rules that deny outbound connections from the API service to RFC1918 and link-local ranges
  • Disable the scanFeeds GraphQL operation at the gateway if the feature is not required
bash
# Kubernetes NetworkPolicy example blocking API egress to internal ranges
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: omnivore-api-egress
spec:
  podSelector:
    matchLabels:
      app: omnivore-api
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
              - 169.254.0.0/16
              - 127.0.0.0/8

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.