This is less a wide-open front door and more a tripwire hidden in one hallway
CVE-2026-46727 is a race-condition-driven use-after-free in Ruby's pthread-based getaddrinfo timeout handler. In plain terms: if an application on Ruby 4.0.0 through 4.0.4 calls Addrinfo.getaddrinfo(..., timeout:) or Socket.tcp(..., resolv_timeout:), and an attacker can make DNS replies land right around the timeout boundary, the Ruby process can dereference freed memory and crash. Ruby upstream says Ruby 3.4 and earlier are not affected, and the fix lands in Ruby 4.0.5; 4.1.0-dev before the fix was also affected in development builds.
The vendor's HIGH 8.1 score prices in the worst-case memory-corruption potential, but that overshoots most real deployments. The decisive friction is that this is not generic unauthenticated internet-to-RCE: the attacker typically needs influence over DNS timing or a malicious resolver path, the target must actually use the vulnerable timeout-bearing APIs, and the currently documented outcome is a process crash, while code execution remains theoretical. For a 10,000-host estate, this is a selective reliability and availability issue, not an all-hands perimeter fire.
4 steps from start to impact.
Gain DNS-path influence
- Unauthenticated remote position is not enough by itself; attacker must influence authoritative or recursive DNS behavior
- Target application must resolve attacker-chosen or attacker-influenced hostnames
- Victim network must permit DNS lookups through the affected path
- Most enterprises use fixed internal recursive resolvers, reducing direct attacker control
- Applications often resolve stable internal or allowlisted names, not attacker-chosen domains
- Egress filtering, split-horizon DNS, or private service discovery can remove the attacker from the lookup path
Hit the vulnerable Ruby code path
Addrinfo.getaddrinfo(..., timeout:) or Socket.tcp(..., resolv_timeout:). An attacker would typically exercise this with application traffic that triggers outbound connection attempts or hostname resolution. Tooling is mundane here—just the app's own request flow plus a DNS server that can shape latency.- Ruby runtime version in affected range
- Application uses the affected APIs with explicit timeout options
- Attacker can trigger the relevant application behavior remotely
- Many Ruby estates will still be on 3.x, which upstream marks unaffected
- Not every app passes
timeout:orresolv_timeout:at all - Some vulnerable hosts may be build tools or workers, not internet-reachable services
Win the race at the timeout boundary
rb_getaddrinfo. The attacker delays the DNS response so it arrives near the configured timeout, attempting to force use-after-free behavior. A lab setup could use Scapy or a customized DNS server to tune response timing, but this is still high-complexity exploitation.- Predictable enough timeout values and network timing
- Repeated attempts against a stable target path
- The process remains reachable long enough for race attempts
- Race windows are timing-sensitive and environment-dependent
- Container scheduling, resolver caching, retries, and network jitter reduce reliability
- Successful reproduction in one environment does not guarantee portability
Crash the process; anything beyond that is speculative
- The race condition is triggered successfully
- The vulnerable process handles the bad state without prior termination or recovery
- Observed and vendor-described impact is crash, not demonstrated code execution
- Modern memory allocators and runtime behavior may make controlled exploitation much harder than simple process termination
The supporting signals.
| In-the-wild status | No evidence found of active exploitation in the reviewed primary sources; not KEV-listed. |
|---|---|
| Proof-of-concept availability | No public PoC located in the reviewed sources. The underlying report is referenced via HackerOne report 3607434, but public exploit code was not confirmed. |
| EPSS | 0.00161 from the user-provided intel, which is extremely low in absolute probability terms; percentile was not independently confirmed from an authoritative EPSS query during this assessment. |
| KEV status | No. The CISA KEV catalog did not show this CVE in the reviewed sources. |
| CVSS vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — the key flag is AC:H. That high complexity is not cosmetic here; timing control and DNS-path influence are real exploit friction. |
| Affected versions | Upstream lists Ruby 4.0.0 through 4.0.4 and Ruby 4.1.0-dev before the fix as affected; Ruby 3.4 and earlier are not affected. |
| Fixed versions | Upstream fix is Ruby 4.0.5 or later. Distros may eventually backport fixes without exposing the upstream version number, so package-level validation matters on managed Linux builds. |
| Scanning and exposure reality | There is no meaningful internet-banner census for this bug. Shodan/Censys-style exposure counts are poor proxies because this is a runtime/API-path issue inside Ruby applications, not a directly fingerprintable network service version. |
| Disclosure timeline | Ruby published the advisory on 2026-05-20; NVD shows the CVE published on 2026-05-22. |
| Reporter / patch credit | Discovery credited by Ruby to cantina-security; patch credit goes to shioimm. |
noisgate verdict.
The single most important downgrading factor is attacker position and path control: this is only reachable when the attacker can influence DNS timing against a very specific Ruby 4 code path. That sharply narrows the exposed population, and the documented real-world impact is a crash, not demonstrated remote code execution.
Why this verdict
- Downgrade for attacker path control: vendor starts at 8.1, but real exploitation usually requires influence over authoritative/recursive DNS timing, which implies a narrower attacker position than plain internet reachability.
- Downgrade for conditional code reachability: only Ruby 4.0.0–4.0.4 is affected, and only when applications call
Addrinfo.getaddrinfo(..., timeout:)orSocket.tcp(..., resolv_timeout:); that is not the default shape of every Ruby deployment. - Downgrade for observed impact: upstream explicitly describes process crash, while NVD says memory-corruption exploitation is only *theoretically possible*; absent a public RCE chain or active exploitation, availability is the practical planning assumption.
Why not higher?
This is not a broad, low-friction perimeter bug. The exploit path compounds several prerequisites: affected Ruby 4 adoption, a timeout-bearing API call, attacker influence over DNS timing, and then winning a race. That combination is enough friction to keep it out of HIGH despite the scary memory-corruption label.
Why not lower?
It still deserves attention because the bug is remotely triggerable in the right application pattern and can take down a production Ruby process. For organizations running Ruby 4 services that make attacker-influenced outbound lookups with explicit resolver timeouts, the availability impact is real enough that calling it LOW would understate operational risk.
What to do — in priority order.
- Inventory Ruby 4 estates — Find hosts, containers, CI runners, and app images carrying Ruby 4.0.0–4.0.4 and map which services are internet-facing or process attacker-influenced hostnames. For a MEDIUM verdict there is no mitigation SLA, but do this during normal vulnerability hygiene and feed the actual patch plan into the 365-day remediation window.
- Remove vulnerable timeout usage where feasible — If you own the code and cannot upgrade immediately, stop passing
timeout:toAddrinfo.getaddrinfoandresolv_timeout:toSocket.tcp, exactly as Ruby upstream recommends. There is no mitigation SLA for MEDIUM here, so treat this as a risk-reduction option rather than an emergency outage-control mandate. - Constrain DNS trust paths — Force application egress through trusted internal recursive resolvers, block ad hoc resolver use, and review services that resolve attacker-supplied hostnames. This matters because the exploit chain becomes much less realistic when the attacker cannot shape DNS timing; implement as standard hardening within the same 365-day remediation window.
- Alert on crash patterns — Add monitoring for Ruby worker restarts, segfaults, lookup timeouts, and bursts of failed DNS resolution in affected services. This will not prevent exploitation, but it improves detection of attempted crash-inducing activity while you work through remediation.
- A generic WAF does little here because the dangerous condition is in outbound DNS resolution timing inside the application, not a simple inbound HTTP signature.
- Relying only on external vuln scanning will miss the real exposure question; scanners can spot Ruby versions, but they usually cannot prove that the app uses the vulnerable timeout-bearing APIs.
- Assuming 'not internet-exposed' means safe is sloppy for worker tiers; background jobs and internal services may still resolve attacker-influenced hostnames and hit the vulnerable path.
Crowdsourced verification payload.
Run this on the target Linux or macOS host that has the Ruby interpreter installed, or inside the affected container image. Invoke it as bash check_cve_2026_46727.sh /usr/bin/ruby or simply bash check_cve_2026_46727.sh to use ruby from PATH; no root is required, but package-manager metadata checks may return more detail when available.
#!/usr/bin/env bash
# check_cve_2026_46727.sh
# Determine likely exposure to CVE-2026-46727 based on local Ruby version.
# Outputs one of: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -u
RUBY_BIN="${1:-ruby}"
have_cmd() {
command -v "$1" >/dev/null 2>&1
}
version_ge() {
# returns 0 if $1 >= $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" ]
}
version_gt() {
# returns 0 if $1 > $2
[ "$1" != "$2" ] && version_ge "$1" "$2"
}
version_lt() {
# returns 0 if $1 < $2
! version_ge "$1" "$2"
}
if ! have_cmd "$RUBY_BIN"; then
echo "UNKNOWN - ruby binary not found: $RUBY_BIN"
exit 2
fi
RAW_VER="$($RUBY_BIN -e 'print RUBY_VERSION' 2>/dev/null)"
if [ -z "$RAW_VER" ]; then
echo "UNKNOWN - unable to read RUBY_VERSION from $RUBY_BIN"
exit 2
fi
# Upstream advisory scope:
# affected: 4.0.0 through 4.0.4
# fixed: 4.0.5+
# unaffected: 3.4 and earlier
if version_ge "$RAW_VER" "4.0.0" && version_lt "$RAW_VER" "4.0.5"; then
PKG_HINT=""
if have_cmd dpkg-query; then
PKG_HINT="; distro package backports are possible, verify package changelog if this is vendor-managed"
elif have_cmd rpm; then
PKG_HINT="; distro package backports are possible, verify rpm changelog if this is vendor-managed"
fi
echo "VULNERABLE - Ruby version $RAW_VER is in upstream affected range 4.0.0-4.0.4$PKG_HINT"
exit 1
fi
if version_ge "$RAW_VER" "4.0.5"; then
echo "PATCHED - Ruby version $RAW_VER is at or above upstream fixed version 4.0.5"
exit 0
fi
if version_lt "$RAW_VER" "4.0.0"; then
echo "PATCHED - Ruby version $RAW_VER is below Ruby 4 and outside upstream affected range"
exit 0
fi
# Catch development/pre-release or unusual builds that don't compare cleanly to stable semantics.
echo "UNKNOWN - Ruby version $RAW_VER could not be mapped cleanly to the upstream advisory; verify whether this is a 4.1.0-dev build before the fix"
exit 2
If you remember one thing.
Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.