about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-04-27 17:06:47 +0200
committerGitHub <noreply@github.com>2017-04-27 17:06:47 +0200
commit2af4f3c4e22ab9a28a7fca49bee0ee2ed6256f27 (patch)
tree073f68695a0da1ee7dcf2f909a449b60286ad3f4 /app/services
parentb8e7eee8372f927a5a3b51e95db3707d34c4ac4b (diff)
Improve shared status verification (#2525)
* Instead of parsing shared status contents verbatim, make roundtrip
to purported original URL. Confirm that the "original" URL is from the
same domain as the author it claims to be from.

* Fix obvious typo, add comment

* Use URI look-up first

* Add test, update Goldfinger dependency to make less useless HTTP requests per Webfinger lookup
Diffstat (limited to 'app/services')
-rw-r--r--app/services/fetch_remote_status_service.rb12
-rw-r--r--app/services/process_feed_service.rb12
2 files changed, 21 insertions, 3 deletions
diff --git a/app/services/fetch_remote_status_service.rb b/app/services/fetch_remote_status_service.rb
index c666961ad..5a454808e 100644
--- a/app/services/fetch_remote_status_service.rb
+++ b/app/services/fetch_remote_status_service.rb
@@ -39,9 +39,19 @@ class FetchRemoteStatusService < BaseService
 
     Rails.logger.debug "Going to webfinger #{username}@#{domain}"
 
-    return FollowRemoteAccountService.new.call("#{username}@#{domain}")
+    account = FollowRemoteAccountService.new.call("#{username}@#{domain}")
+
+    # If the author's confirmed URLs do not match the domain of the URL
+    # we are reading this from, abort
+    return nil unless confirmed_domain?(domain, account)
+
+    account
   rescue Nokogiri::XML::XPath::SyntaxError
     Rails.logger.debug 'Invalid XML or missing namespace'
     nil
   end
+
+  def confirmed_domain?(domain, account)
+    domain.casecmp(account.domain).zero? || domain.casecmp(Addressable::URI.parse(account.remote_url).normalize.host).zero?
+  end
 end
diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb
index d002b9130..799a9f6e3 100644
--- a/app/services/process_feed_service.rb
+++ b/app/services/process_feed_service.rb
@@ -47,8 +47,8 @@ class ProcessFeedService < BaseService
       return status unless just_created
 
       if verb == :share
-        original_status, = status_from_xml(@xml.at_xpath('.//activity:object', activity: TagManager::AS_XMLNS))
-        status.reblog    = original_status
+        original_status = shared_status_from_xml(@xml.at_xpath('.//activity:object', activity: TagManager::AS_XMLNS))
+        status.reblog   = original_status
 
         if original_status.nil?
           status.destroy
@@ -90,6 +90,14 @@ class ProcessFeedService < BaseService
       !([:post, :share, :delete].include?(verb) && [:activity, :note, :comment].include?(type))
     end
 
+    def shared_status_from_xml(entry)
+      status = find_status(id(entry))
+
+      return status unless status.nil?
+
+      FetchRemoteStatusService.new.call(url(entry))
+    end
+
     def status_from_xml(entry)
       # Return early if status already exists in db
       status = find_status(id(entry))