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

CVE-2026-16194: zhayujie CowAgent SSRF Vulnerability

CVE-2026-16194 is a server-side request forgery flaw in zhayujie CowAgent affecting versions up to 2.1.1. Attackers can exploit the WebFetch.execute function remotely. This article covers technical details, impact, and patches.

Published:

CVE-2026-16194 Overview

CVE-2026-16194 is a Server-Side Request Forgery (SSRF) vulnerability in zhayujie CowAgent versions up to 2.1.1. The flaw resides in the WebFetch.execute function within agent/tools/web_fetch/web_fetch.py. Attackers can manipulate the url argument to force the agent to issue HTTP requests to arbitrary destinations, including internal services, loopback addresses, and cloud metadata endpoints. The issue is tracked as [CWE-918] and has been publicly disclosed. The vendor released version 2.1.2 with commit ea47f3097eed4f8295c4cb3d76ecb97e0f43d632 to remediate the flaw.

Critical Impact

Remote authenticated attackers can coerce the CowAgent backend into contacting internal-only endpoints, potentially exposing metadata services and non-public network resources.

Affected Products

  • zhayujie CowAgent versions up to and including 2.1.1
  • The agent/tools/web_fetch/web_fetch.py module (WebFetch.execute function)
  • Fixed in CowAgent 2.1.2

Discovery Timeline

  • 2026-07-18 - CVE-2026-16194 published to NVD
  • 2026-07-20 - Last updated in NVD database

Technical Details for CVE-2026-16194

Vulnerability Analysis

CowAgent is an LLM-driven agent framework that exposes a WebFetch tool allowing the model to retrieve content from URLs supplied at runtime. Before version 2.1.2, the WebFetch.execute function accepted any URL without validating the resolved destination. Because the model can be steered by user input, an attacker can indirectly control the url argument passed into the tool. The agent then performs the outbound HTTP request from the server's network context, bypassing perimeter filtering.

The attack requires network reachability and low-level privileges to interact with the agent, but no user interaction beyond crafting a prompt or request. Successful exploitation exposes internal-only services, RFC1918 hosts, IPv6 unique local addresses, and cloud metadata endpoints such as 169.254.169.254.

Root Cause

The root cause is missing destination validation on model-supplied URLs. The pre-patch WebFetch implementation trusted the scheme and hostname without resolving the address or checking whether it fell within a private, loopback, link-local, reserved, multicast, or unspecified range. This aligns with the classic SSRF pattern described in [CWE-918].

Attack Vector

An attacker who can influence the prompt or tool arguments provides a URL pointing at an internal resource. WebFetch.execute issues the request server-side and returns the response body to the caller. This allows enumeration of internal services and, on cloud-hosted deployments, potential theft of instance credentials from the metadata service.

python
# Post-patch SSRF guard added in commit ea47f3097eed4f8295c4cb3d76ecb97e0f43d632
# File: agent/tools/utils/url_safety.py
"""
Shared SSRF guard utilities for tools that fetch model-supplied URLs.

A URL is only considered safe when it uses an http/https scheme, has a
hostname, that hostname resolves, and every resolved address is a public
(internet-routable) address. Loopback, private (RFC1918 / ULA), link-local
(incl. the 169.254.169.254 cloud-metadata endpoint) and otherwise reserved
addresses are rejected, for both IPv4 and IPv6.
"""

import ipaddress
import socket
from urllib.parse import urlparse


def _is_blocked_ip(ip: "ipaddress._BaseAddress") -> bool:
    """Return True if the address is not safe to connect to (non-public)."""
    return (
        ip.is_private
        or ip.is_loopback
        or ip.is_link_local
        or ip.is_reserved
        or ip.is_multicast
        or ip.is_unspecified
    )


def assert_public_ip(ip_str: str) -> None:
    """Raise ValueError if the given literal IP is a non-public address."""

Source: GitHub Commit ea47f30

Detection Methods for CVE-2026-16194

Indicators of Compromise

  • Outbound HTTP requests from the CowAgent host targeting 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or IPv6 loopback and ULA ranges.
  • Requests originating from CowAgent to the cloud metadata endpoint 169.254.169.254 or IMDSv2 URIs.
  • Tool invocation logs showing WebFetch.execute arguments containing internal hostnames or raw IP literals.

Detection Strategies

  • Instrument the WebFetch tool to log every URL passed to execute and compare resolved IPs against a private-range allowlist.
  • Correlate agent tool-call telemetry with egress firewall logs to identify agents contacting non-public destinations.
  • Alert on any HTTP client activity from the CowAgent process contacting link-local or reserved address space.

Monitoring Recommendations

  • Forward CowAgent application logs and host network telemetry to a centralized analytics platform for anomaly detection.
  • Baseline normal outbound destinations for the agent workload and alert on deviations.
  • Monitor cloud IAM audit logs for unexpected use of instance-role credentials that could indicate metadata theft.

How to Mitigate CVE-2026-16194

Immediate Actions Required

  • Upgrade CowAgent to version 2.1.2 or later, which includes the url_safety guard.
  • Audit agent tool invocation logs for prior WebFetch calls targeting internal or metadata endpoints.
  • Rotate any cloud credentials or API tokens accessible from the CowAgent host if metadata access is suspected.

Patch Information

The vendor released the fix in commit ea47f3097eed4f8295c4cb3d76ecb97e0f43d632, published as CowAgent v2.1.2. The patch introduces agent/tools/utils/url_safety.py, which validates the URL scheme, resolves the hostname, and rejects loopback, private, link-local, reserved, multicast, and unspecified addresses for both IPv4 and IPv6. See the GitHub Pull Request #2900 and GitHub Issue #2889 for review context.

Workarounds

  • Deploy CowAgent behind an egress proxy that blocks connections to RFC1918, loopback, link-local, and 169.254.169.254.
  • Run the agent in a network namespace or container without routes to internal management networks or the cloud metadata service.
  • Enforce IMDSv2 with hop-limit 1 on AWS-hosted deployments to reduce metadata credential exposure.
bash
# Upgrade CowAgent to the patched release
git clone https://github.com/zhayujie/CowAgent.git
cd CowAgent
git checkout 2.1.2
pip install -r requirements.txt

# Optional: enforce IMDSv2 on AWS hosts running CowAgent
aws ec2 modify-instance-metadata-options \
  --instance-id i-0123456789abcdef0 \
  --http-tokens required \
  --http-put-response-hop-limit 1

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.