Jul 30, 2026·6 min read·3 visits
Flyto2 Core follows HTTP redirects to private internal subnets without revalidating intermediate URLs, leading to an SSRF vulnerability (CVSS 8.5).
An SSRF vulnerability exists in Flyto2 Core due to improper validation of intermediate HTTP redirect hops. While the initial request target is validated against an SSRF protection policy, the HTTP client library (aiohttp) transparently follows 30x redirects to local, internal, or cloud metadata endpoints without application-level revalidation.
The Flyto2 Core engine is designed to execute automation and artificial intelligence workflows by exposing dynamic orchestration modules. Under normal operational patterns, users utilize modules such as http.get, http.request, and http.batch to retrieve remote resources or execute webhooks. Because these execution runners operate on the internal network boundary of the host system, they expose a highly sensitive network attack surface.
To restrict access to internal infrastructure, the application uses an SSRF guard mechanism named validate_url_with_env_config(url). This validation tool resolves hostnames and asserts that target destinations do not lie within loopback addresses, local network subnets, or metadata addresses. If a user supplies a protected address directly, the application throws an exception and halts execution.
However, a severe design gap exists in how the engine processes downstream network redirections. While the initial request destination undergoes validation, intermediate HTTP redirection targets do not. This vulnerability allows an external, untrusted target to pivot the execution runner into restricted subnets by responding with standard redirection status codes.
The primary logical failure resides in the configuration of the Python aiohttp HTTP client library used by the request modules. When initializing execution sessions, the application relies on the default network client behavior where the redirect policy is configured with automatic redirection enabled (allow_redirects=True). Consequently, the socket handling layer resolves the redirection at the socket layer without returning control to the parent validation application.
The sequential flaw unfolds when an execution session resolves a public hostname that points to a legitimate external address. The application resolves the target host, verifies it does not match internal IP blocks, and initiates the socket connection. When the external server responds with a redirection status code (such as HTTP 301, 302, 303, 307, or 308) and a Location header, the underlying client immediately executes the subsequent request.
Because the redirection handling occurs transparently within the client library, the application-level validation layer is completely bypassed. If the Location header points to a private loopback target (such as http://127.0.0.1:8500) or cloud instance metadata endpoints (such as http://169.254.169.254/latest/meta-data), the client will establish the socket connection, retrieve the data, and expose internal configuration files or credential secrets.
The remediation committed in version 2.26.7 focuses on modifying the redirection behavior within src/core/utils.py. The patch explicitly disables automatic redirection on the HTTP client library and replaces it with a manual hop-by-hop checking loop.
# Patched implementation of aiohttp wrapper
_REDIRECT_STATUSES = frozenset({301, 302, 303, 307, 308})
async def guarded_aiohttp_request(session, method: str, url: str, *,
max_redirects: int = 5, **kwargs):
from urllib.parse import urljoin
# Explicitly remove allow_redirects if passed by the caller
kwargs.pop('allow_redirects', None)
guard = ssrf_protection_enabled()
if guard:
# Validate the initial URL input
validate_url_with_env_config(url)
method = method.upper()
for hop in range(max_redirects + 1):
# Execute request with automatic redirection disabled
response = await session.request(method, url, allow_redirects=False, **kwargs)
location = response.headers.get('Location')
# Manually intercept redirection status
if response.status in _REDIRECT_STATUSES and location and hop < max_redirects:
response.release() # Prevent connection socket leakage
url = urljoin(url, location)
if guard:
# REVALIDATE EACH INTERMEDIATE HOP AGAINST THE GUARD POLICY
validate_url_with_env_config(url)
if response.status == 303:
method = 'GET'
kwargs.pop('json', None)
kwargs.pop('data', None)
continue
return response
return responseBy disabling automatic redirects at the library layer via allow_redirects=False, the application intercepts every redirect. The code resolves relative URLs using urljoin and evaluates the resolved URL string against validate_url_with_env_config(url). If any redirect hop target maps to a restricted IP address range, the system raises an SSRFError, terminating the connection.
An attacker with privileges to configure or trigger a workflow block can exploit this vulnerability to extract confidential credentials from cloud environments. The target runner environment must have access to the internal network space or a cloud metadata endpoint.
To conduct the attack, the adversary registers an external domain and configures it to return redirection response headers pointing to the targeted internal service. For example, a redirect script running on an external server can respond with:
HTTP/1.1 302 Found
Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-roleWhen the Flyto2 Core engine initiates the execution of the workflow block containing the external URL, the initial validation check resolves the domain to a public IP. The request proceeds, gets redirected, and because of automatic redirect tracking, queries the cloud metadata endpoint, returning the administrative AWS credentials to the attacker inside the workflow output logs.
The impact of this SSRF bypass is rated high (CVSS v3.1 base score of 8.5). Successful exploitation allows authenticated users with execution privileges to read arbitrary internal configurations, network service responses, database details, and cloud metadata records.
By obtaining access to loopback interfaces, an attacker can exploit other unauthenticated services residing on the local host. For example, local microservices, caches, and queue systems that assume safety within the network perimeter can be read and manipulated. Furthermore, in containerized environments, attackers can pull access tokens belonging to the Kubernetes node or host instance, enabling lateral movement and escalating privileges across the broader cluster deployment.
The recommended remediation is to immediately update flyto-core to version 2.26.7 or later. This upgrade deploys the custom request handler that manually checks and isolates redirection hops.
In addition to upgrading, security operators should implement host-level network egress restrictions. Restricting runner instances from accessing local subnets (such as 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and blocklisting the cloud metadata address (169.254.169.254) via firewall rules (such as iptables or security groups) establishes a defense-in-depth model that prevents exploitation even in the presence of library-level validation bypasses.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:L/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
flyto-core flytohub | < 2.26.7 | 2.26.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-918 |
| Attack Vector | Network |
| CVSS Base Score | 8.5 |
| EPSS Score | 0.00236 |
| EPSS Percentile | 14.80% |
| Exploit Status | poc |
| KEV Status | Not listed |
The application constructs an outbound HTTP request using a client-controlled URL destination without proper validation of intermediate redirects, allowing access to private resources.
Flyto2 Core (flyto-core) prior to version 2.26.7 did not utilize its centralized SSRF validation mechanism ('validate_url_with_env_config') across multiple HTTP-emitting modules. This oversight allowed low-privileged users executing automated workflows to perform Server-Side Request Forgery (SSRF) attacks against internal endpoints, loopback interfaces, and cloud provider metadata services.
A logic vulnerability exists in @dynatrace-oss/dynatrace-mcp-server prior to version 1.8.7. The create_dynatrace_notebook tool lacks a human-approval gate, allowing an attacker to exploit indirect prompt injection to force the underlying LLM client to create persistent Dynatrace notebooks without the operator's consent.
A critical authentication and authorization bypass vulnerability in the Quarkus Java framework exists due to a parser differential mismatch between the HTTP security policy layer and downstream handlers. By leveraging encoded reserved characters such as semicolons, slashes, and backslashes, attackers can bypass configured path-based security policies to gain unauthorized access to secure administrative endpoints and static resources.
A critical code injection vulnerability exists in @aws/agentcore CLI (AWS AgentCore CLI) during the Bedrock Agent import lifecycle. An authenticated remote attacker with permissions to configure Bedrock collaborator attributes can inject python code by embedding triple-double-quotes (""") inside the collaborationInstruction metadata field. The CLI formats this metadata directly into a Python docstring in a generated main.py file without adequate escaping, leading to arbitrary code execution when the imported agent is run or deployed.
GHSA-WCHH-9X6H-7F6P documents the critical deprecation of the cryptographic library libolm (Olm) and its Python binding wrapper python-olm, which matrix-commander depended upon via its downstream client library matrix-nio. Multiple cryptographic vulnerabilities (timing leaks, side-channels, signature malleability, and protocol confusion) were disclosed in 2022 and 2024. Because libolm is unmaintained, Python clients using matrix-commander are considered cryptographically unsafe until migrating to vodozemac.
An Excessive Data Exposure vulnerability in Easy!Appointments v1.5.2 allows low-privileged administrative users, such as restricted Providers and Secretaries, to harvest unique, stateless appointment hashes belonging to other providers. These hashes act as capability tokens, granting full authorization to reschedule, take over, or delete appointments via stateless endpoints, resulting in a complete Broken Object Level Authorization (BOLA) scenario.