VYPR
High severityNVD Advisory· Published Jun 13, 2018· Updated Sep 16, 2024

CVE-2018-3759

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.

PackageAffected versionsPatched versions
private_address_checkRubyGems
< 0.5.00.5.0

Affected products

2

Patches

1
4068228187db

Fix 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

News mentions

0

No linked articles in our index yet.