diff --git a/Gemfile b/Gemfile index d7864b379..d21adf4d7 100644 --- a/Gemfile +++ b/Gemfile @@ -42,7 +42,7 @@ gem 'builder' # gem 'did_you_mean' # github.com/yuki24/did_you_mean/issues/117 gem 'puma' gem 'scenic' -gem 'ipaddress' +gem 'ipaddress_2' gem 'http' gem 'activerecord-hierarchical_query' gem 'pundit' diff --git a/Gemfile.lock b/Gemfile.lock index 9bb0f9c86..423429faa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -171,7 +171,7 @@ GEM multi_xml (>= 0.5.2) i18n (1.8.2) concurrent-ruby (~> 1.0) - ipaddress (0.8.3) + ipaddress_2 (0.13.0) jmespath (1.4.0) jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) @@ -443,7 +443,7 @@ DEPENDENCIES flamegraph http httparty - ipaddress + ipaddress_2 jquery-rails listen mail diff --git a/app/logical/downloads/file.rb b/app/logical/downloads/file.rb index 13ed9c7d5..8bbab504b 100644 --- a/app/logical/downloads/file.rb +++ b/app/logical/downloads/file.rb @@ -95,15 +95,25 @@ module Downloads ip_addr = IPAddr.new(Resolv.getaddress(url.hostname)) CloudflareService.new.ips.any? { |subnet| subnet.include?(ip_addr) } end + + def self.banned_ip?(ip) + ip = IPAddress.parse(ip.to_s) unless ip.is_a?(IPAddress) + + if ip.ipv4? + ip.loopback? || ip.link_local? || ip.multicast? || ip.private? + elsif ip.ipv6? + ip.loopback? || ip.link_local? || ip.unique_local? || ip.unspecified? + end + end end # Hook into HTTParty to validate the IP before following redirects. # https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/ConnectionAdapter class ValidatingConnectionAdapter < HTTParty::ConnectionAdapter def self.call(uri, options) - ip_addr = IPAddr.new(::Resolv.getaddress(uri.hostname)) + ip_addr = IPAddress.parse(::Resolv.getaddress(uri.hostname)) - if Danbooru.config.banned_ip_for_download?(ip_addr) + if Downloads::File.banned_ip?(ip_addr) raise Downloads::File::Error, "Downloads from #{ip_addr} are not allowed" end diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index dcbbdb1a6..b33bc9799 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -392,39 +392,6 @@ module Danbooru "zDMSATq0W3hmA5p3rKTgD" end - # For downloads, if the host matches any of these IPs, block it - def banned_ip_for_download?(ip_addr) - raise ArgumentError unless ip_addr.is_a?(IPAddr) - - if ip_addr.ipv4? - if IPAddr.new("127.0.0.1") == ip_addr - true - elsif IPAddr.new("169.254.0.0/16").include?(ip_addr) - true - elsif IPAddr.new("10.0.0.0/8").include?(ip_addr) - true - elsif IPAddr.new("172.16.0.0/12").include?(ip_addr) - true - elsif IPAddr.new("192.168.0.0/16").include?(ip_addr) - true - else - false - end - elsif ip_addr.ipv6? - if IPAddr.new("::1") == ip_addr - true - elsif IPAddr.new("fe80::/10").include?(ip_addr) - true - elsif IPAddr.new("fd00::/8").include?(ip_addr) - true - else - false - end - else - false - end - end - # The url of the Discord server associated with this site. def discord_server_url nil