CVE-2026-100863: Heym before 0.0.91 SSRF via image fetching and IPv6 validation
Heym versions 0.0.90 and earlier contain two server-side request forgery (SSRF) egress gaps, both remediated in app/services/ssrfguard.py in 0.0.91. First, the LLM image-edit input loader (loadimagebytes) fetched caller-controlled HTTP/HTTPS URLs with a bare httpx.get, applying only a scheme check and bypassing the egress-pinning HTTP client; because the workflow DSL supports "imageInput": "$userInput.body.imageUrl", a webhook or API caller can choose the fetch target when a workflow author uses that expression, allowing requests to loopback, RFC1918, and cloud metadata endpoints. Second, ispublicaddress unwrapped only IPv4-mapped IPv6 addresses, so IPv6 transition forms — the NAT64 well-known prefix 64:ff9b::/96, deprecated IPv4-compatible ::x.x.x.x addresses, and 6to4 (2002::/16, classified as globally routable by Python 3.11.0 through 3.11.9) — could carry loopback, RFC1918, link-local, or cloud-metadata IPv4 destinations past both the initial URL validation and the dial-time IP pin. Version 0.0.91 routes the image loader through guardhttpurl and the guarded client, evaluates NAT64 and IPv4-compatible addresses by their embedded IPv4 address, and refuses 64:ff9b:1::/48, 6to4, and Teredo (2001::/32) outright.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Heymto a version that resolves this vulnerability.Fixed in 0.0.91
Event History
Frequently Asked Questions
Which deployments are most exposed to the image-fetching issue?
Deployments are exposed when a workflow author uses the DSL expression "imageInput": "$userInput.body.imageUrl" and webhook or API callers can supply that value. In affected versions, a caller can select the HTTP or HTTPS fetch target.
What internal targets could an attacker reach?
The described gaps can allow requests to loopback, RFC1918 private-address, link-local, and cloud metadata endpoints. IPv6 transition representations may be used to carry such IPv4 destinations past validation and dial-time pinning.
Are IPv6 addresses relevant even if direct private IPv4 targets are filtered?
Yes. Affected validation did not correctly handle NAT64 addresses in 64:ff9b::/96, deprecated IPv4-compatible ::x.x.x.x addresses, and 6to4 addresses in 2002::/16; these forms could embed disallowed IPv4 destinations.
What version contains the remediation?
Version 0.0.91 remediates both issues. It sends image loading through guard_http_url and the guarded client, evaluates NAT64 and IPv4-compatible addresses using their embedded IPv4 address, and refuses the stated IPv6 ranges.