CVE-2018-3759
Description
private_address_check ruby gem before 0.5.0 is vulnerable to a time-of-check time-of-use (TOCTOU) race condition due to the address the socket uses not being checked. DNS entries with a TTL of 0 can trigger this case where the initial resolution is a public address but the subsequent resolution is a private address.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
private_address_check Ruby gem before 0.5.0 has a TOCTOU race condition where DNS TTL 0 can bypass private address checks, enabling SSRF.
Vulnerability
The private_address_check Ruby gem versions before 0.5.0 are vulnerable to a time-of-check time-of-use (TOCTOU) race condition [1]. The gem fails to check the address the socket actually uses after resolving a hostname. DNS entries with a TTL of 0 can trigger this race: the initial resolution yields a public address (passing the check), but a subsequent resolution returns a private address that is used for the actual connection [2].
Exploitation
An attacker needs control over a DNS record with a TTL of 0 that initially resolves to a public IP address (passing the gem's check) and then quickly changes to a private IP address (e.g., 10.0.0.1, 192.168.1.1). The victim application must use the resolves_to_private_address? or only_public_connections method without the TCPSocket extension [2]. The attacker can then serve a link or resource that triggers the application to make a request to the attacker-controlled domain, causing the race to succeed [3].
Impact
Successful exploitation allows an attacker to bypass the private address check, enabling Server-Side Request Forgery (SSRF) attacks. The attacker can make the application connect to internal network resources (e.g., cloud metadata endpoints, internal services) that would otherwise be blocked. This can lead to information disclosure or further compromise of internal systems [1][3].
Mitigation
Upgrade to version 0.5.0 or later of the private_address_check gem, which includes the fix for this race condition [3]. If upgrading is not immediately possible, use the TCPSocket extension (require 'private_address_check/tcpsocket_ext') which checks the actual socket address after connection. Alternatively, implement a caching DNS resolver (e.g., dnsmasq, unbound) with a minimum cache time to override TTL 0 entries [3]. The vulnerability is also tracked in the Ruby Advisory Database [4].
AI Insight generated on May 22, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
private_address_checkRubyGems | < 0.5.0 | 0.5.0 |
Affected products
2- HackerOne/private_address_check ruby gemv5Range: 0.5.0
Patches
14068228187dbFix TOCTOU bug
3 files changed · +19 −6
lib/private_address_check/tcpsocket_ext.rb+3 −4 modified@@ -14,11 +14,10 @@ def only_public_connections TCPSocket.class_eval do alias initialize_without_private_address_check initialize - def initialize(remote_host, remote_port, local_host = nil, local_port = nil) - if Thread.current[:private_address_check] && PrivateAddressCheck.resolves_to_private_address?(remote_host) + def initialize(*args) + initialize_without_private_address_check(*args) + if Thread.current[:private_address_check] && PrivateAddressCheck.resolves_to_private_address?(remote_address.ip_address) raise PrivateAddressCheck::PrivateConnectionAttemptedError end - - initialize_without_private_address_check(remote_host, remote_port, local_host, local_port) end end
README.md+11 −1 modified@@ -61,8 +61,18 @@ To install this gem onto your local machine, run `bundle exec rake install`. To Bug reports and pull requests are welcome on GitHub at https://github.com/jtdowney/private_address_check. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. +## Security + +If you've found a security issue in `private_address_check`, please reach out to @jtdowney via email to report. + +### Time of check to time of use + +A library like `private_address_check` is going to be easily susceptible to attacks like [time of check to time of use](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use). DNS entries with a TTL of 0 can trigger this case where the initial resolution is a public address by the subsequent resolution is a private address. There are some possible defenses and workarounds: + +- Use the TCPSocket extension in this library which checks the address the socket uses. This is most useful if your system is built on native Ruby like Net::HTTP. +- Use a feature like the `resolve` capability in curl and [curb](https://www.rubydoc.info/github/taf2/curb/Curl/Easy#resolve=-instance_method) to force the resolution to a pre-checked IP address. +- Implement your own caching DNS resolver with something like dnsmasq or unbound. These tools let you set a minimum cache time that can override the TTL of 0. ## License The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). -
test/private_address_check/tcpsocket_ext_test.rb+5 −1 modified@@ -3,11 +3,15 @@ class TCPSocketExtTest < Minitest::Test def test_private_address + server = TCPServer.new(63453) + thread = Thread.start { server.accept } assert_raises PrivateAddressCheck::PrivateConnectionAttemptedError do PrivateAddressCheck.only_public_connections do - TCPSocket.new("localhost", 80) + TCPSocket.new("localhost", 63453) end end + ensure + thread.exit if thread end def test_public_address
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4- github.com/advisories/GHSA-2xvj-j3qh-x8c3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2018-3759ghsaADVISORY
- github.com/jtdowney/private_address_check/commit/4068228187db87fea7577f7020099399772bb147ghsax_refsource_MISCWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/private_address_check/CVE-2018-3759.ymlghsaWEB
News mentions
0No linked articles in our index yet.