CVE-2026-70620 Overview
CVE-2026-70620 is a server-side request forgery (SSRF) vulnerability in Odysseus, a local-first embedding server. Versions prior to commit 87babb5 fail to validate user-supplied URLs submitted to the embedding endpoint configuration API. An admin-privileged attacker can point the endpoint at loopback addresses, RFC 1918 ranges, or link-local addresses. The server then issues outbound requests to those targets and returns partial responses to the attacker. This exposes cloud instance metadata services, internal APIs, and other hosts reachable from the Odysseus host. The flaw is tracked under CWE-918.
Critical Impact
Attackers with admin access can pivot into internal networks and read cloud metadata credentials via the embedding endpoint configuration API.
Affected Products
- Odysseus (all versions prior to commit 87babb5)
- Odysseus embedding endpoint API (POST /api/embeddings/endpoint)
- Deployments exposing the admin API to untrusted operators
Discovery Timeline
- 2026-08-04 - CVE-2026-70620 published to NVD
- 2026-08-05 - Last updated in NVD database
Technical Details for CVE-2026-70620
Vulnerability Analysis
Odysseus supports custom embedding backends by allowing administrators to configure an outbound URL through POST /api/embeddings/endpoint. The server then issues an httpx request to that URL to perform a health check and subsequent embedding calls. Before commit 87babb5, the endpoint handler accepted any URL string without validating the scheme, host, resolved IP address, or DNS rebind behavior. Because Odysseus proxies the response back to the client, an attacker can partially read responses from arbitrary reachable hosts. On cloud deployments, the link-local address 169.254.169.254 exposes the instance metadata service, which typically returns temporary IAM credentials.
Root Cause
The root cause is missing input validation on a user-supplied URL prior to an outbound HTTP request. The pre-patch handler checked only that a URL string was present. It did not enforce an allowlist of schemes, did not resolve the hostname to check the destination IP, and did not reject private, loopback, link-local, multicast, or reserved ranges. This maps directly to CWE-918: Server-Side Request Forgery.
Attack Vector
An attacker who already holds admin credentials on the Odysseus instance sends a crafted request to the embedding endpoint configuration API. The submitted URL targets an internal resource such as http://169.254.169.254/latest/meta-data/iam/security-credentials/ on AWS, http://127.0.0.1: for local admin services, or an RFC 1918 host on the internal LAN. Odysseus performs the outbound request and returns response data to the caller. Non-HTTP schemes such as file:// and gopher:// were also accepted prior to the patch.
# Security patch: SSRF hardening in routes/embedding_routes.py
if not url:
raise HTTPException(400, "URL is required")
# SSRF hardening: validate the user-supplied URL before any outbound
# request. Local-first means loopback/LAN endpoints are allowed by
# default; non-HTTP(S) schemes and the cloud metadata range are always
# rejected. Set EMBEDDING_BLOCK_PRIVATE_IPS=true for full lockdown.
from src.url_safety import check_outbound_url
ok, reason = check_outbound_url(
url,
block_private=os.getenv("EMBEDDING_BLOCK_PRIVATE_IPS", "false").lower() == "true",
)
if not ok:
raise HTTPException(400, f"Rejected endpoint URL: {reason}")
# Quick health check
try:
import httpx
Source: GitHub commit 87babb5
Detection Methods for CVE-2026-70620
Indicators of Compromise
- Requests to POST /api/embeddings/endpoint containing URLs with loopback (127.0.0.0/8), link-local (169.254.0.0/16, fe80::/10), or RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) targets
- Outbound httpx requests from the Odysseus process to 169.254.169.254 or other cloud metadata endpoints
- Embedding endpoint values referencing non-HTTP(S) schemes such as file://, gopher://, or ftp://
- Unexpected access patterns in cloud audit logs originating from the Odysseus workload identity
Detection Strategies
- Monitor Odysseus application logs for configuration changes to the embedding endpoint URL and correlate them with subsequent outbound traffic
- Inspect egress network flows from the Odysseus host for connections to internal or metadata address ranges that are not part of normal operation
- Alert on cloud provider metadata service access from workloads that historically do not query it
Monitoring Recommendations
- Enable audit logging for all admin API calls, particularly embedding endpoint configuration changes
- Deploy egress filtering telemetry to record destination IPs and hostnames for Odysseus outbound HTTP requests
- Track authentication events for admin accounts on Odysseus and flag configuration changes made from unexpected sources
How to Mitigate CVE-2026-70620
Immediate Actions Required
- Upgrade Odysseus to a build containing commit 87babb5 or later
- Set the environment variable EMBEDDING_BLOCK_PRIVATE_IPS=true for any multi-tenant or internet-exposed deployment
- Rotate any cloud IAM credentials that were reachable via the instance metadata service on the affected host
- Audit admin accounts on Odysseus and remove unused or shared credentials
Patch Information
The fix is delivered in commit 87babb5, which adds a new src/url_safety.py module and a check_outbound_url call in the embedding route handler. The patch enforces an HTTP(S) scheme allowlist, always rejects link-local, multicast, reserved, and unspecified addresses, and rejects non-HTTP schemes such as file:// and gopher://. Additional lockdown is available through the EMBEDDING_BLOCK_PRIVATE_IPS environment variable. See the VulnCheck SSRF advisory and the GitHub pull request for further context.
Workarounds
- Restrict access to the Odysseus admin API to trusted operators via network ACLs or reverse proxy authentication
- Enforce IMDSv2 on AWS workloads to require session tokens for metadata access
- Apply egress network policies that block outbound traffic from Odysseus to 169.254.169.254 and internal management ranges
- Run Odysseus in a namespace or container with no route to sensitive internal services
# Enable full SSRF lockdown for exposed deployments
export EMBEDDING_BLOCK_PRIVATE_IPS=true
# Example egress restriction using iptables to block cloud metadata
iptables -A OUTPUT -d 169.254.169.254 -j REJECT
# AWS: enforce IMDSv2 to require session tokens
aws ec2 modify-instance-metadata-options \
--instance-id i-0123456789abcdef0 \
--http-tokens required \
--http-endpoint enabled
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

