NewApp Monitoring is liveSign up free
AgentbeamBeta
AI agent vulnerability · Other MCP servers and tools

CVE-2026-67428: Flyto2 Core: Multiple HTTP-family modules fetch client-controlled URLs without the SSRF guard their siblings apply (SSRF to internal/metadata)

highCVSS 3.1 8.5GHSA-pgwh-4jj4-qm8v

Many HTTP-making modules in flyto-core, including core.api.http_get and http_post, fetch a caller-supplied URL without calling the project's SSRF guard. An authenticated workflow author, or an agent acting for one, can reach the cloud metadata endpoint or internal hosts and read the response. Versions up to 2.26.6 are affected. Fixed in 2.26.7.

Published Jul 30, 2026 · Analysis Oct 25, 2026

What an attacker can do

flyto-core's SSRF guard, validate_url_with_env_config, is per-module. There is no global egress filter. The affected modules never call it and only carry an ssrf_protected tag string that enforces nothing. In developer/http/requests.py, session.get(url) runs at line 85 and session.post at line 188 with no check. SECURITY.md wrongly lists api.http_get as protected.

The affected set: core.api.http_get and http_post, graphql.query and mutation, monitor.http_check, communication.slack_send, the Discord, Slack and Teams notification modules, ai.vision_analyze on its Anthropic path, verify.visual_diff, browser.proxy_rotate, and the inline base_url branch of agent and llm.

The response (status code, headers, body) comes back to the caller. In the reporter's test, core.api.http_get returned an internal body from a loopback server while the guarded sibling http.get answered Hostname blocked: 127.0.0.1. A direct IP works, so no bypass trick is needed. The attacker needs a valid workflow-author token on POST /mcp execute_module, or a prompt-injected agent. They can steal cloud IAM credentials from 169.254.169.254 and read or write internal services.

Who is affected

flyto-core 2.26.6 and earlier (pip package flyto-core). The vulnerable code was confirmed on the v2.26.6 release tag. The core.api.* modules were not on the default module denylist, so they were callable out of the box.

pip show flyto-core

flyto-core

Ecosystem
PyPI
Affected
<= 2.26.6
Fixed in
2.26.7
Check
pip show flyto-core

How to fix it

Upgrade to flyto-core 2.26.7:

pip install --upgrade flyto-core==2.26.7

The fix commit adds an enforce_outbound_url() helper and calls it before outbound requests in the listed modules, including requests.py, vision_analyze, proxy_rotate, slack_send, the graphql modules, monitor.http_check and verify.visual_diff. Most raise an error wrapping SSRFError. http_check and visual_diff return error_code SSRF_BLOCKED instead.

The same commit also adds redirect revalidation for http.get, http.request and http.batch, capped at 5 hops, and requires a shared key on the verification /run endpoint. Those are covered by separate advisories. Block metadata-endpoint access from the host as defense in depth.

How to tell if you were hit

Review MCP and API logs for execute_module calls to core.api.http_get, http_post, graphql, monitor.http_check or notification modules whose url points at 169.254.169.254, loopback, RFC1918 ranges or internal hostnames. On the network side, look for requests from the flyto-core host to the metadata service. If one occurred, treat the instance role credentials as exposed and rotate them. After the upgrade, SSRF_BLOCKED results or SSRFError exceptions mark blocked attempts. Beam records agent MCP tool calls, so such execute_module arguments can be reviewed.

Original advisory

From the GitHub Advisory Database (CC BY 4.0).

Summary

Numerous HTTP-emitting modules (core.api.http_get, core.api.http_post, graphql.query/graphql.mutation, monitor.http_check, communication.slack_send, notification.{discord,slack,teams}.send_message, ai.vision_analyze [anthropic path], verify.visual_diff, browser.proxy_rotate, and the agent/llm inline base_url branch) perform outbound requests to a fully client-controlled URL without calling the project's own SSRF guard (validate_url_with_env_config) that their sibling modules apply. An authenticated workflow-author can point the URL at the cloud metadata IP (169.254.169.254), a loopback/RFC1918 host, or any internal host and read the response, yielding cloud-metadata credential theft and internal service read/write.

Root Cause

The SSRF guard is per-module (there is NO global egress interception). Each module must call validate_url_with_env_config before issuing a request. The listed modules never call it — they only carry an ssrf_protected metadata tag string which enforces nothing. Exemplar: src/core/modules/third_party/developer/http/requests.py — grepping for validate_url|ssrf|is_private in requests.py returns 0 guard calls; session.get(url) fires at :85 (HTTPGetModule) and session.post at :188 (HTTPPostModule). SECURITY.md incorrectly lists api.http_get as SSRF-protected.

Impact

Readable SSRF: full {status_code, headers, body} returned to the caller (requests.py:96-108). Enables theft of cloud IAM credentials from the metadata endpoint and read/write access to internal-only APIs. Scope Changed (S:C) — the request crosses into cloud-metadata / internal-network authority the workflow layer does not otherwise have.

Proof of Concept

Verified live this session: core.api.http_get with url pointed at a loopback internal server returned the internal body INTERNAL-SECRET-IAM-CREDENTIALS, while the guarded sibling http.get returned NETWORK_ERROR: Hostname blocked: 127.0.0.1 on the same input — proving the branch-asymmetry is real (not a port artifact).

POST /mcp {"method":"tools/call","params":{"name":"execute_module",
  "arguments":{"module_id":"core.api.http_get",
  "params":{"url":"http://<cloud-metadata-ip>/latest/meta-data/iam/security-credentials/"}}}}

Attack Chain

  1. Entry: authenticated MCP client → POST /mcp execute_module core.api.http_get, url set to the cloud metadata endpoint. Guard: require_auth (mcp.py:71). Bypass proof: passes with a valid workflow-author bearer token (PR:L).
  2. Check: capability denylist / enforce_module_policy (base.py:240). Bypass proof: core.api.* not in _DEFAULT_DENYLIST (module_policy.py:45-67) → is_allowed=True (runtime-registration verified: core.api.http_get -> HTTPGetModule).
  3. Check: SSRF validation. Bypass proof: requests.py has ZERO validate_url/ssrf calls — only the ssrf_protected tag string at :23/:116. session.get(url) fires at :85.
  4. Sink: aiohttp GET/POST to the cloud metadata IP.
  5. Impact: full response body returned → IAM credential theft, internal read/write.

Bypass Evidence

Grepping validate_url|ssrf|is_private in requests.py → 0 guard calls (2 hits are both the inert tag string). Live PoC returned internal body directly; guarded sibling blocked the same input. Direct IP works — no IPv6 transition trick needed (AC:L), unlike the seed CVE-2026-55787.

Affected Versions

<= 2.26.6 — code present on latest release tag v2.26.6 (requests.py:19,112).

Suggested Fix

Call validate_url_with_env_config(url) in each listed module before issuing the outbound request, matching the guarded siblings (e.g. ai.model:157, http.get). Best: route all outbound HTTP through a single guarded client wrapper so new modules inherit the guard.

Credit

Vulnerability discovered by zx (Jace).

Credited to manus-use.

Questions

Why did http.get block the request but core.api.http_get did not?

http.get calls the SSRF guard before sending. core.api.http_get never did; it carried only a metadata tag. The reporter's test showed the same loopback input blocked by one and served by the other.

Does the attacker need an account?

The advisory scores low privileges: a valid workflow-author bearer token on POST /mcp. A prompt-injected agent that holds such access can do the same.

Which version fixes CVE-2026-67428?

flyto-core 2.26.7. Versions up to 2.26.6 are affected.

References

How this page is made: the data panel comes from the GitHub Advisory Database, CISA’s KEV catalog, the NVD and FIRST EPSS, and updates twice a day. The analysis is written by an AI model from the sources listed above and checked by automated rules before it is published. Check versions against the vendor's advisory before you act. Methodology

More Other MCP servers and tools vulnerabilities

All Other MCP servers and tools entries