diff --git a/lib/final_destination/ssrf_detector.rb b/lib/final_destination/ssrf_detector.rb index 8ee0a3f49bc..aeb01d9ec90 100644 --- a/lib/final_destination/ssrf_detector.rb +++ b/lib/final_destination/ssrf_detector.rb @@ -2,8 +2,8 @@ class FinalDestination module SSRFDetector - class DisallowedIpError < SocketError - end + class DisallowedIpError < SocketError; end + class LookupFailedError < SocketError; end def self.standard_private_ranges @private_ranges ||= [ @@ -61,7 +61,12 @@ class FinalDestination end def self.lookup_and_filter_ips(name, timeout: nil) - ips = lookup_ips(name, timeout: timeout) + begin + ips = lookup_ips(name, timeout: timeout) + rescue SocketError + raise LookupFailedError, "FinalDestination: lookup failed" + end + return ips if host_bypasses_checks?(name) ips.filter! { |ip| FinalDestination::SSRFDetector.ip_allowed?(ip) } diff --git a/lib/retrieve_title.rb b/lib/retrieve_title.rb index 2a258c3b0e1..df1355ded3c 100644 --- a/lib/retrieve_title.rb +++ b/lib/retrieve_title.rb @@ -9,7 +9,7 @@ module RetrieveTitle max_redirects: max_redirects, initial_https_redirect_ignore_limit: initial_https_redirect_ignore_limit ) - rescue Net::ReadTimeout + rescue Net::ReadTimeout, FinalDestination::SSRFDetector::LookupFailedError # do nothing for Net::ReadTimeout errors end diff --git a/spec/lib/final_destination/ssrf_detector_spec.rb b/spec/lib/final_destination/ssrf_detector_spec.rb index bd4b5e12a88..6d24a9ca3af 100644 --- a/spec/lib/final_destination/ssrf_detector_spec.rb +++ b/spec/lib/final_destination/ssrf_detector_spec.rb @@ -95,6 +95,13 @@ describe FinalDestination::SSRFDetector do ) end + it "raises an exception if lookup fails" do + subject.stubs(:lookup_ips).raises(SocketError) + expect { subject.lookup_and_filter_ips("example.com") }.to raise_error( + subject::LookupFailedError, + ) + end + it "bypasses filtering for allowlisted hosts" do SiteSetting.allowed_internal_hosts = "example.com" subject.stubs(:lookup_ips).returns(["127.0.0.1"]) diff --git a/spec/lib/retrieve_title_spec.rb b/spec/lib/retrieve_title_spec.rb index b59ff8d1b20..1826a162348 100644 --- a/spec/lib/retrieve_title_spec.rb +++ b/spec/lib/retrieve_title_spec.rb @@ -162,7 +162,13 @@ RSpec.describe RetrieveTitle do it "it ignores Net::ReadTimeout errors" do stub_request(:get, "https://example.com").to_raise(Net::ReadTimeout) - expect { RetrieveTitle.crawl("https://example.com") }.not_to raise_error + expect(RetrieveTitle.crawl("https://example.com")).to eq(nil) + end + + it "ignores SSRF lookup errors" do + subject.stubs(:fetch_title).raises(FinalDestination::SSRFDetector::LookupFailedError) + + expect(RetrieveTitle.crawl("https://example.com")).to eq(nil) end end