about summary refs log tree commit diff
path: root/app/lib/request.rb
diff options
context:
space:
mode:
authorAkihiko Odaki <akihiko.odaki.4i@stu.hosei.ac.jp>2018-02-25 03:16:11 +0900
committerEugen Rochko <eugen@zeonfederated.com>2018-02-24 19:16:11 +0100
commit2e8a492e8843aa958c53636b24cf4d344e7ca47d (patch)
treee921f2ad9ecde98d57f7a65ff3d729ff003ec5d4 /app/lib/request.rb
parent7cb49eaa3aad03b60a1e1620d2f700d6ed2b3ea0 (diff)
Raise Mastodon::HostValidationError when host for HTTP request is private (#6410)
Diffstat (limited to 'app/lib/request.rb')
-rw-r--r--app/lib/request.rb19
1 files changed, 18 insertions, 1 deletions
diff --git a/app/lib/request.rb b/app/lib/request.rb
index 7671f4ffc..5776b3d78 100644
--- a/app/lib/request.rb
+++ b/app/lib/request.rb
@@ -1,5 +1,8 @@
 # frozen_string_literal: true
 
+require 'ipaddr'
+require 'socket'
+
 class Request
   REQUEST_TARGET = '(request-target)'
 
@@ -8,7 +11,7 @@ class Request
   def initialize(verb, url, **options)
     @verb    = verb
     @url     = Addressable::URI.parse(url).normalize
-    @options = options
+    @options = options.merge(socket_class: Socket)
     @headers = {}
 
     set_common_headers!
@@ -87,4 +90,18 @@ class Request
   def http_client
     HTTP.timeout(:per_operation, timeout).follow(max_hops: 2)
   end
+
+  class Socket < TCPSocket
+    class << self
+      def open(host, *args)
+        address = IPSocket.getaddress(host)
+        raise Mastodon::HostValidationError if PrivateAddressCheck.private_address? IPAddr.new(address)
+        super address, *args
+      end
+
+      alias new open
+    end
+  end
+
+  private_constant :Socket
 end