diff --git a/lib/geocoder/request.rb b/lib/geocoder/request.rb index 06990fe65afb836f6ffec9d55f90c6a08e8e1de9..5e2eb6c99db3f79bbcc47e0fed9128e97293f910 100644 --- a/lib/geocoder/request.rb +++ b/lib/geocoder/request.rb @@ -1,3 +1,5 @@ +require 'ipaddr' + module Geocoder module Request @@ -54,6 +56,8 @@ module Geocoder GEOCODER_CANDIDATE_HEADERS.each do |header| if @env.has_key? header addrs = geocoder_split_ip_addresses(@env[header]) + addrs = geocoder_remove_port_from_addresses(addrs) + addrs = geocoder_reject_non_ipv4_addresses(addrs) addrs = geocoder_reject_trusted_ip_addresses(addrs) return addrs.first if addrs.any? end @@ -75,6 +79,23 @@ module Geocoder def geocoder_reject_trusted_ip_addresses(ip_addresses) ip_addresses.reject { |ip| trusted_proxy?(ip) } end + + def geocoder_remove_port_from_addresses(ip_addresses) + ip_addresses.map { |ip| ip.split(':').first } + end + + def geocoder_reject_non_ipv4_addresses(ip_addresses) + ips = [] + for ip in ip_addresses + begin + valid_ip = IPAddr.new(ip) + rescue + valid_ip = false + end + ips << valid_ip.to_s if valid_ip + end + return ips.any? ? ips : ip_addresses + end end end diff --git a/test/unit/request_test.rb b/test/unit/request_test.rb index f44df34853f07d081ebc8156e77fed73d11c3be5..127f5f4f36c508f08229cc897e7f9ea707d008db 100644 --- a/test/unit/request_test.rb +++ b/test/unit/request_test.rb @@ -66,4 +66,28 @@ class RequestTest < GeocoderTestCase assert_equal 'RD', req.safe_location.country_code assert_equal 'US', req.location.country_code end -end + def test_geocoder_remove_port_from_addresses_with_port + expected_ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3'] + ips = ['127.0.0.1:3000', '127.0.0.2:8080', '127.0.0.3:9292'] + req = MockRequest.new() + assert_equal expected_ips, req.send(:geocoder_remove_port_from_addresses, ips) + end + def test_geocoder_remove_port_from_addresses_without_port + expected_ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3'] + ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3'] + req = MockRequest.new() + assert_equal expected_ips, req.send(:geocoder_remove_port_from_addresses, ips) + end + def test_geocoder_reject_non_ipv4_addresses_with_good_ips + expected_ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3'] + ips = ['127.0.0.1', '127.0.0.2', '127.0.0.3'] + req = MockRequest.new() + assert_equal expected_ips, req.send(:geocoder_reject_non_ipv4_addresses, ips) + end + def test_geocoder_reject_non_ipv4_addresses_with_bad_ips + expected_ips = ['127.0.0.1'] + ips = ['127.0.0', '127.0.0.1', '127.0.0.2.0'] + req = MockRequest.new() + assert_equal expected_ips, req.send(:geocoder_reject_non_ipv4_addresses, ips) + end +end \ No newline at end of file