Every CVE Search/ Get API key

CVE-2026-55787

Flyto2 Core: SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

7.1 HighFix available

Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.3, validate_url_ssrf and is_private_ip in src/core/utils.py compare resolved addresses only against native private IPv4 and IPv6 ranges and do not unwrap IPv4-mapped, IPv4-compatible, 6to4, or NAT64 transition addresses. An authenticated workflow author can provide a transition-form literal URL through the Execution API POST /v1/execute route, http.get, or sibling guarded outbound-request modules, causing the guard to accept an address whose embedded IPv4 points to loopback, RFC 1918, or cloud metadata services. On a host that routes the selected transition form, the outbound request reaches the internal destination and returns the response body to the workflow caller, enabling read SSRF and disclosure of internal-service data or cloud credentials. This issue is fixed in version 2.26.3.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
Low
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
Low
Availability
None

Exploit likelihood

0.29%Up 0.1 points since Oct 15, 2026
90%50%10%1%

What each source reports

CVE List Score used 7.1

Flyto2 Core: SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.3, validate_url_ssrf and is_private_ip in src/core/utils.py compare resolved addresses only against native private IPv4 and IPv6 ranges and do not unwrap IPv4-mapped, IPv4-compatible, 6to4, or NAT64 transition addresses. An authenticated workflow author can provide a transition-form literal URL through the Execution API POST /v1/execute route, http.get, or sibling guarded outbound-request modules, causing the guard to accept an address whose embedded IPv4 points to loopback, RFC 1918, or cloud metadata services. On a host that routes the selected transition form, the outbound request reaches the internal destination and returns the response body to the workflow caller, enabling read SSRF and disclosure of internal-service data or cloud credentials. This issue is fixed in version 2.26.3.

Record
CVE-2026-55787
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-918
Updated
2026-11-02
EUVDEUVD-2026-101588 7.1

Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.3, validate_url_ssrf and is_private_ip in src/core/utils.py compare resolved addresses only against native private IPv4 and IPv6 ranges and do not unwrap IPv4-mapped, IPv4-compatible, 6to4, or NAT64 transition addresses. An authenticated workflow author can provide a transition-form literal URL through the Execution API POST /v1/execute route, http.get, or sibling guarded outbound-request modules, causing the guard to accept an address whose embedded IPv4 points to loopback, RFC 1918, or cloud metadata services. On a host that routes the selected transition form, the outbound request reaches the internal destination and returns the response body to the workflow caller, enabling read SSRF and disclosure of internal-service data or cloud credentials. This issue is fixed in version 2.26.3.

Record
EUVD-2026-101588
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-794r-5rp2-fpg8 7.1

flyto-core has SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

Summary

flyto-core's SSRF protection (validate_url_ssrf / is_private_ip in src/core/utils.py) blocks private and metadata destinations by resolving the host and testing the resulting IP for membership in a hardcoded PRIVATE_IP_RANGES list. That list contains only the native RFC 1918 / loopback / link-local / unique-local ranges. It does not account for IPv6 transition address forms that embed an IPv4 (or loopback) target:

  • IPv4-mapped ::ffff:a.b.c.d
  • IPv4-compatible ::a.b.c.d
  • 6to4 2002::/16
  • NAT64 well-known prefix 64:ff9b::/96 and local-use 64:ff9b:1::/48

A workflow author can submit a URL with a literal transition-form host (for example http://[::ffff:127.0.0.1]:8080/... or http://[64:ff9b::a9fe:a9fe]/latest/meta-data/). is_private_ip() returns False for these (the address is not literally inside any listed range), so validate_url_ssrf lets the request through, and the http.get atomic module (and ~10 sibling modules that share the same guard) performs the outbound aiohttp fetch and returns the response body. On a host that uses NAT64/6to4 these addresses route to the embedded IPv4 endpoint (e.g. the cloud instance-metadata service 169.254.169.254); on any dual-stack host the IPv4-mapped form is routed by the kernel directly to the embedded IPv4, including loopback and RFC 1918 internal services.

This is CWE-918 (Server-Side Request Forgery): the guard that exists specifically to keep workflow-authored URLs away from internal/metadata endpoints is bypassable, and the response body is returned to the caller (a read SSRF).

Affected code

src/core/utils.py:

  • PRIVATE_IP_RANGES (around L297) — lists native ranges only; no 64:ff9b::/96, no 2002::/16, no ::ffff:0:0/96, no ::/96.
  • is_private_ip(ip_str) (around L337) — ipaddress.ip_address(ip_str) then membership test against PRIVATE_IP_RANGES. Because the test is plain network membership (not is_global/is_private predicates), it does not unwrap transition forms, so even ::ffff:127.0.0.1 — which ipaddress itself classifies is_private == True — is not caught here.
  • validate_url_ssrf (around L358) — resolves via socket.getaddrinfo(hostname, None, AF_UNSPEC) and rejects only when is_private_ip(ip) is True.
  • validate_url_with_env_config(url) (around L496) — the wrapper actually invoked by the modules.

Trust boundary in src/core/modules/atomic/http/get.py:

  • L93 url = params.get('url') — workflow parameter, attacker-controlled by the workflow author.
  • L104 validate_url_with_env_config(url) — the guard above.
  • L116 async with session.get(url, headers=headers, ssl=ssl_param) as response — aiohttp fetch; the body is returned to the caller.

How input reaches the sink (reachability)

params['url'] (L93) is fully attacker-controlled by the workflow author. It reaches the sink with no intervening sanitization other than the SSRF guard itself: L93 read → L104 validate_url_with_env_config(url) (the bypassed guard) → L116 aiohttp session.get. The route is POST /v1/execute with body {"module_id":"http.get","params":{"url":...}} (bearer-token authenticated; the token is the per-instance workflow-author credential), or equivalently an http.get node in a workflow YAML. The response body is returned in the data.body field, making this a read SSRF.

The same guarded-then-fetch pattern is shared by the http.{request,batch,paginate,session}, browser.goto, image.download, communication.webhook_trigger, notification.send, vector.connector and llm.chat atomic modules.

Impact

A user who can author/execute a workflow (the product's normal untrusted-input surface — reachable over the Execution API POST /v1/execute with a module-execute body, or via a workflow YAML node) can drive an authenticated outbound GET to internal-only destinations that the SSRF guard is explicitly meant to block:

  • Cloud instance-metadata service…
Record
GHSA-794r-5rp2-fpg8
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-918
Updated
2026-11-02
NVD 7.1

Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.3, validate_url_ssrf and is_private_ip in src/core/utils.py compare resolved addresses only against native private IPv4 and IPv6 ranges and do not unwrap IPv4-mapped, IPv4-compatible, 6to4, or NAT64 transition addresses. An authenticated workflow author can provide a transition-form literal URL through the Execution API POST /v1/execute route, http.get, or sibling guarded outbound-request modules, causing the guard to accept an address whose embedded IPv4 points to loopback, RFC 1918, or cloud metadata services. On a host that routes the selected transition form, the outbound request reaches the internal destination and returns the response body to the workflow caller, enabling read SSRF and disclosure of internal-service data or cloud credentials. This issue is fixed in version 2.26.3.

Record
CVE-2026-55787
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-918
Updated
2026-11-02
OSV 7.1

Flyto2 Core: SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

Flyto2 Core is an execution kernel for automation and AI-agent workflows. Prior to 2.26.3, validate_url_ssrf and is_private_ip in src/core/utils.py compare resolved addresses only against native private IPv4 and IPv6 ranges and do not unwrap IPv4-mapped, IPv4-compatible, 6to4, or NAT64 transition addresses. An authenticated workflow author can provide a transition-form literal URL through the Execution API POST /v1/execute route, http.get, or sibling guarded outbound-request modules, causing the guard to accept an address whose embedded IPv4 points to loopback, RFC 1918, or cloud metadata services. On a host that routes the selected transition form, the outbound request reaches the internal destination and returns the response body to the workflow caller, enabling read SSRF and disclosure of internal-service data or cloud credentials. This issue is fixed in version 2.26.3.

Record
CVE-2026-55787
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-918
Updated
2026-11-02
OSVGHSA-794r-5rp2-fpg8 7.1

flyto-core has SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

Summary

flyto-core's SSRF protection (validate_url_ssrf / is_private_ip in src/core/utils.py) blocks private and metadata destinations by resolving the host and testing the resulting IP for membership in a hardcoded PRIVATE_IP_RANGES list. That list contains only the native RFC 1918 / loopback / link-local / unique-local ranges. It does not account for IPv6 transition address forms that embed an IPv4 (or loopback) target:

  • IPv4-mapped ::ffff:a.b.c.d
  • IPv4-compatible ::a.b.c.d
  • 6to4 2002::/16
  • NAT64 well-known prefix 64:ff9b::/96 and local-use 64:ff9b:1::/48

A workflow author can submit a URL with a literal transition-form host (for example http://[::ffff:127.0.0.1]:8080/... or http://[64:ff9b::a9fe:a9fe]/latest/meta-data/). is_private_ip() returns False for these (the address is not literally inside any listed range), so validate_url_ssrf lets the request through, and the http.get atomic module (and ~10 sibling modules that share the same guard) performs the outbound aiohttp fetch and returns the response body. On a host that uses NAT64/6to4 these addresses route to the embedded IPv4 endpoint (e.g. the cloud instance-metadata service 169.254.169.254); on any dual-stack host the IPv4-mapped form is routed by the kernel directly to the embedded IPv4, including loopback and RFC 1918 internal services.

This is CWE-918 (Server-Side Request Forgery): the guard that exists specifically to keep workflow-authored URLs away from internal/metadata endpoints is bypassable, and the response body is returned to the caller (a read SSRF).

Affected code

src/core/utils.py:

  • PRIVATE_IP_RANGES (around L297) — lists native ranges only; no 64:ff9b::/96, no 2002::/16, no ::ffff:0:0/96, no ::/96.
  • is_private_ip(ip_str) (around L337) — ipaddress.ip_address(ip_str) then membership test against PRIVATE_IP_RANGES. Because the test is plain network membership (not is_global/is_private predicates), it does not unwrap transition forms, so even ::ffff:127.0.0.1 — which ipaddress itself classifies is_private == True — is not caught here.
  • validate_url_ssrf (around L358) — resolves via socket.getaddrinfo(hostname, None, AF_UNSPEC) and rejects only when is_private_ip(ip) is True.
  • validate_url_with_env_config(url) (around L496) — the wrapper actually invoked by the modules.

Trust boundary in src/core/modules/atomic/http/get.py:

  • L93 url = params.get('url') — workflow parameter, attacker-controlled by the workflow author.
  • L104 validate_url_with_env_config(url) — the guard above.
  • L116 async with session.get(url, headers=headers, ssl=ssl_param) as response — aiohttp fetch; the body is returned to the caller.

How input reaches the sink (reachability)

params['url'] (L93) is fully attacker-controlled by the workflow author. It reaches the sink with no intervening sanitization other than the SSRF guard itself: L93 read → L104 validate_url_with_env_config(url) (the bypassed guard) → L116 aiohttp session.get. The route is POST /v1/execute with body {"module_id":"http.get","params":{"url":...}} (bearer-token authenticated; the token is the per-instance workflow-author credential), or equivalently an http.get node in a workflow YAML. The response body is returned in the data.body field, making this a read SSRF.

The same guarded-then-fetch pattern is shared by the http.{request,batch,paginate,session}, browser.goto, image.download, communication.webhook_trigger, notification.send, vector.connector and llm.chat atomic modules.

Impact

A user who can author/execute a workflow (the product's normal untrusted-input surface — reachable over the Execution API POST /v1/execute with a module-execute body, or via a workflow YAML node) can drive an authenticated outbound GET to internal-only destinations that the SSRF guard is explicitly meant to block:

  • Cloud instance-metadata service…
Record
GHSA-794r-5rp2-fpg8
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Weakness
CWE-918
Updated
2026-11-02
OSVPYSEC-2026-2481 7.1

flyto-core has SSRF guard bypass via IPv6 transition addresses (IPv4-mapped / 6to4 / NAT64) in validate_url_ssrf

Summary

flyto-core's SSRF protection (validate_url_ssrf / is_private_ip in src/core/utils.py) blocks private and metadata destinations by resolving the host and testing the resulting IP for membership in a hardcoded PRIVATE_IP_RANGES list. That list contains only the native RFC 1918 / loopback / link-local / unique-local ranges. It does not account for IPv6 transition address forms that embed an IPv4 (or loopback) target:

  • IPv4-mapped ::ffff:a.b.c.d
  • IPv4-compatible ::a.b.c.d
  • 6to4 2002::/16
  • NAT64 well-known prefix 64:ff9b::/96 and local-use 64:ff9b:1::/48

A workflow author can submit a URL with a literal transition-form host (for example http://[::ffff:127.0.0.1]:8080/... or http://[64:ff9b::a9fe:a9fe]/latest/meta-data/). is_private_ip() returns False for these (the address is not literally inside any listed range), so validate_url_ssrf lets the request through, and the http.get atomic module (and ~10 sibling modules that share the same guard) performs the outbound aiohttp fetch and returns the response body. On a host that uses NAT64/6to4 these addresses route to the embedded IPv4 endpoint (e.g. the cloud instance-metadata service 169.254.169.254); on any dual-stack host the IPv4-mapped form is routed by the kernel directly to the embedded IPv4, including loopback and RFC 1918 internal services.

This is CWE-918 (Server-Side Request Forgery): the guard that exists specifically to keep workflow-authored URLs away from internal/metadata endpoints is bypassable, and the response body is returned to the caller (a read SSRF).

Affected code

src/core/utils.py:

  • PRIVATE_IP_RANGES (around L297) — lists native ranges only; no 64:ff9b::/96, no 2002::/16, no ::ffff:0:0/96, no ::/96.
  • is_private_ip(ip_str) (around L337) — ipaddress.ip_address(ip_str) then membership test against PRIVATE_IP_RANGES. Because the test is plain network membership (not is_global/is_private predicates), it does not unwrap transition forms, so even ::ffff:127.0.0.1 — which ipaddress itself classifies is_private == True — is not caught here.
  • validate_url_ssrf (around L358) — resolves via socket.getaddrinfo(hostname, None, AF_UNSPEC) and rejects only when is_private_ip(ip) is True.
  • validate_url_with_env_config(url) (around L496) — the wrapper actually invoked by the modules.

Trust boundary in src/core/modules/atomic/http/get.py:

  • L93 url = params.get('url') — workflow parameter, attacker-controlled by the workflow author.
  • L104 validate_url_with_env_config(url) — the guard above.
  • L116 async with session.get(url, headers=headers, ssl=ssl_param) as response — aiohttp fetch; the body is returned to the caller.

How input reaches the sink (reachability)

params['url'] (L93) is fully attacker-controlled by the workflow author. It reaches the sink with no intervening sanitization other than the SSRF guard itself: L93 read → L104 validate_url_with_env_config(url) (the bypassed guard) → L116 aiohttp session.get. The route is POST /v1/execute with body {"module_id":"http.get","params":{"url":...}} (bearer-token authenticated; the token is the per-instance workflow-author credential), or equivalently an http.get node in a workflow YAML. The response body is returned in the data.body field, making this a read SSRF.

The same guarded-then-fetch pattern is shared by the http.{request,batch,paginate,session}, browser.goto, image.download, communication.webhook_trigger, notification.send, vector.connector and llm.chat atomic modules.

Impact

A user who can author/execute a workflow (the product's normal untrusted-input surface — reachable over the Execution API POST /v1/execute with a module-execute body, or via a workflow YAML node) can drive an authenticated outbound GET to internal-only destinations that the SSRF guard is explicitly meant to block:

  • Cloud instance-metadata service…
Record
PYSEC-2026-2481
CVSS 3.1
7.1 HighCVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:N
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
flyto-core
PyPI
through 2.26.2
2.26.3
flyto-core
PyPI
before 2.26.3, plus listed versions
1.0.01.0.11.0.21.0.31.0.4
Show 45 moreShow less
1.0.51.0.61.0.71.0.81.0.91.1.01.1.11.11.01.12.01.13.01.14.01.14.11.14.21.15.01.16.01.16.11.16.101.16.21.16.31.16.41.16.51.16.61.16.71.16.81.16.91.2.01.3.01.4.01.5.01.5.11.5.21.5.41.6.01.6.11.6.21.6.31.6.41.6.51.7.01.7.11.7.21.7.31.7.41.7.51.7.6
2.26.3

History

History
RecordedChangedSources
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-55787 is a high vulnerability (CVSS 7.1) in Flytohub Flyto-core, published July 6, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.29%, the 21st percentile. Fixed in flyto-core 2.26.3.

References

This page doesn't list everything

Left out here: 163 versions and the rest of 3 source descriptions. The JSON record has them.

MoveEnter Open