REDHAT-BUG-2462083: SSRF
AIONLYREPORT package: stunnel-5.72-8.el10 ------ Summary: SSRF Bypass in SOCKS Proxy via 0.0.0.0 and IPv4-mapped IPv6 Addresses: stunnel configured with protocol = socks rejects only 127.0.0.0/8 and ::1, allowing a client to bypass the localhost filter via ::ffff:127.0.0.1 and, on some platforms, 0.0.0.0 or :: to reach loopback-only services on the stunnel host. Requirements to exploit: The package must be deployed in SOCKS server mode (protocol = socks), the attacker must be able to reach that listener, and a service of interest must be bound to loopback on the stunnel host. Some deployments may additionally gate access with network policy or TLS client authentication. The strongest reproduced bypass uses ::ffff:127.0.0.1; the 0.0.0.0 and :: variants are additional edge cases and may be OS-dependent. Component affected: stunnel-5.72-8.el10, src/protocol.c, validateconnectaddr() in the SOCKS server request path Version affected: stunnel-5.72-8.el10 when configured with protocol = socks Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L - 8.1 (HIGH) AV:N - A reachable protocol = socks listener can be attacked over the network with a crafted SOCKS request. AC:L - The bypass only requires a crafted destination address and no race or unusual precondition once the listener is reachable. PR:N - The SOCKS server path accepts the 0x00 no-authentication method; no prior privileges on the host are required. UI:N - No user interaction is required. S:U - The issue is an access-control failure in stunnel's own destination validation and is scored within that service boundary. C:H - Successful exploitation can expose loopback-only administrative, metadata, or data-bearing services that were intentionally not network-reachable. I:L - Some local services may accept state-changing requests once the loopback-only boundary is bypassed, but that impact is deployment-dependent. A:L - Unintended requests to local services can also create limited service disruption or load. Impact: Important. When stunnel is deployed as a reachable SOCKS server, a client that can reach the listener can bypass the intended localhost restriction and access services that should only be reachable from the local host. Under Red Hat's guidance this is closer to Important than Moderate because it can expose protected resources to a remote client of the vulnerable service and may enable limited integrity or availability impact as a follow-on. It is not Critical because it does not by itself provide system compromise or code execution, and it is limited to the supported but non-default protocol = socks configuration. Embargo: no Reason: The issue is limited to deployments that intentionally enable protocol = socks, and operators can immediately reduce exposure by disabling or tightly restricting the SOCKS listener. It is serious for affected deployments, but it is not a default-path or wormable compromise. Acknowledgement: Aisle Research Vulnerability Details: The directly observed flaw is an incomplete destination filter in validateconnectaddr(). The function rejects IPv4 loopback (127.0.0.0/8) and exact IPv6 loopback (::1), but it does not reject IPv4-mapped IPv6 loopback such as ::ffff:127.0.0.1, and it also leaves the unspecified addresses 0.0.0.0 and :: unchecked. c NOEXPORT int validateconnectaddr(CLI c) { #ifdef USEIPv6 const unsigned char ipv6loopback[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; #endif unsigned i; for(i=0; i<c->connectaddr.num; ++i) { SOCKADDRUNION addr=&c->connectaddr.addr[i]; #ifdef USEIPv6 if(addr->sa.safamily==AFINET6) { if(!memcmp(&addr->in6.sin6addr, ipv6loopback, 16)) { slog(LOGERR, "SOCKS connection to the IPv6 loopback rejected"); return 0; } / TODO: implement more checks / } else #endif if(addr->sa.safamily==AFINET) { if((ntohl(addr->in.sinaddr.saddr)&0xff000000)==0x7f000000) { slog(LOGERR, "SOCKS connection to the IPv4 loopback rejected"); return 0; } / TODO: implement more checks / } else { slog(LOGERR, "Unsupported address type 0x%02x", addr->sa.safamily); return 0; } } return 1; } The same validation helper is used before the normal outbound connect path (connectremote() -> sconnect() -> connect()). As a result, a client can supply ::ffff:127.0.0.1 and reach a service bound only to loopback on the stunnel host. The 0.0.0.0 and :: variants should be treated more cautiously because their behavior is OS-dependent, but they remain unfiltered edge cases. The strongest reproduced case is the IPv4-mapped IPv6 loopback path on IPv6-enabled builds. The downstream impact depends on what services are bound to loopback and whether those services apply their own authentication. Steps to reproduce: 1. Configure stunnel SOCKS server: ini [socksserver] protocol = socks accept = 127.0.0.1:9080 cert = stunnel.pem key = stunnel.key 2. Start a localhost-only target service on the same host: bash nc -lv 127.0.0.1 18080 3. Open a TLS session to stunnel and perform SOCKS5 handshake: bash openssl sclient -quiet -connect 127.0.0.1:9080 4. Send method negotiation bytes 05 01 00. 5. Send a connect request to ::ffff:127.0.0.1:18080: 05 01 00 04 00000000000000000000ffff7f000001 46a0 6. Observe stunnel replies success (REP=0x00) and data reaches the localhost listener. 7. Repeat with 0.0.0.0 / :: as additional edge cases; these may be OS-dependent, while IPv4-mapped IPv6 loopback is the strongest reproducible bypass case. Mitigation: If SOCKS proxying is not required, disable protocol = socks. Otherwise do not expose the SOCKS listener to untrusted clients, keep it bound to loopback or a trusted management network where possible, and enforce any available client-authentication or network ACL controls until a code fix is shipped. Proposed Fix: A minimal fix is to reject IPv4 and IPv6 unspecified addresses and to detect IPv4-mapped IPv6 loopback before returning success from validateconnectaddr(). diff diff --git a/src/protocol.c b/src/protocol.c @@ NOEXPORT int validateconnectaddr(CLI c) { #ifdef USEIPv6 const unsigned char ipv6loopback[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + const unsigned char ipv6any[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; #endif @@ #ifdef USEIPv6 if(addr->sa.safamily==AFINET6) { if(!memcmp(&addr->in6.sin6addr, ipv6loopback, 16)) { slog(LOGERR, "SOCKS connection to the IPv6 loopback rejected"); return 0; } + if(!memcmp(&addr->in6.sin6addr, ipv6any, 16)) { + slog(LOGERR, + "SOCKS connection to the IPv6 unspecified address rejected"); + return 0; + } + if(!memcmp(addr->in6.sin6addr.s6addr, + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff", 12) && + ((addr->in6.sin6addr.s6addr[12] & 0xff)==0x7f)) { + slog(LOGERR, + "SOCKS connection to the IPv4-mapped IPv6 loopback rejected"); + return 0; + } / TODO: implement more checks / } else #endif if(addr->sa.safamily==AFINET) { + if(ntohl(addr->in.sinaddr.saddr)==0x00000000) { + slog(LOGERR, + "SOCKS connection to the IPv4 unspecified address rejected"); + return 0; + } if((ntohl(addr->in.sinaddr.saddr)&0xff000000)==0x7f000000) { slog(LOGERR, "SOCKS connection to the IPv4 loopback rejected"); return 0; } ------ This report was generated using AI technology. Always review AI-generated content prior to use
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
If SOCKS proxying is not required, disable `protocol = socks` in stunnel to avoid exposing the SOCKS server request path where localhost-filter bypass via crafted addresses can occur.
stunnel protocol = socks (disable if not required) - Configuration
Harden `validate_connect_addr()` in the SOCKS server request path to reject IPv4-mapped IPv6 loopback (e.g., `::ffff:127.0.0.1`) and also reject unspecified destination address edge cases (`0.0.0.0` and `::`) before returning success (i.e., do not allow the SOCKS server to accept connect requests to those destinations).
stunnel (src/protocol.c validate_connect_addr) validate_connect_addr() destination address checks = reject IPv4-mapped IPv6 loopback and unspecified addresses (0.0.0.0 / ::) - Compensating control
Ensure any stunnel SOCKS listener is not reachable by untrusted clients: bind the SOCKS listener to loopback only (e.g., `accept = 127.0.0.1:9080`) or a trusted management network, and gate access with network policy/TLS client authentication or network ACLs until destination address validation is fixed.
Event History
Frequently Asked Questions
What is the severity of REDHAT-BUG-2462083?
The severity of REDHAT-BUG-2462083 is classified as medium with a CVSS score of 4.
How do I fix REDHAT-BUG-2462083?
To mitigate REDHAT-BUG-2462083, update the stunnel package to the latest version to address the SSRF vulnerability.
What type of vulnerability is REDHAT-BUG-2462083?
REDHAT-BUG-2462083 is an SSRF bypass vulnerability in the SOCKS Proxy configuration of stunnel.
What are the components affected by REDHAT-BUG-2462083?
The affected component for REDHAT-BUG-2462083 is the stunnel package, specifically version 5.72-8.el10.
When was REDHAT-BUG-2462083 published?
REDHAT-BUG-2462083 was published on April 26, 2026.