about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/helpers/autoreject_helper.rb53
-rw-r--r--app/lib/activitypub/activity.rb34
-rw-r--r--app/services/activitypub/fetch_remote_account_service.rb7
-rw-r--r--app/services/activitypub/fetch_remote_status_service.rb8
-rw-r--r--app/services/activitypub/fetch_replies_service.rb7
5 files changed, 75 insertions, 34 deletions
diff --git a/app/helpers/autoreject_helper.rb b/app/helpers/autoreject_helper.rb
new file mode 100644
index 000000000..1fed32c3d
--- /dev/null
+++ b/app/helpers/autoreject_helper.rb
@@ -0,0 +1,53 @@
+module AutorejectHelper
+	def should_reject?(uri = nil)
+    if @json
+      oid = @json['id']
+      return true if ENV.fetch('REJECT_IF_ID_STARTS_WITH', '').split.any? { |r| oid.start_with?(r) }
+      return true if ENV.fetch('REJECT_IF_ID_CONTAINS', '').split.any? { |r| r.in?(oid) }
+    end
+
+    if uri.nil?
+      if @object
+        uri = object_uri.start_with?('http') ? object_uri : @object['url']
+      elsif @json
+        uri = @json['id']
+      end
+    end
+
+    return if uri.nil?
+
+    domain = uri.scan(/[\w\-]+\.[\w\-]+(?:\.[\w\-]+)*/).first
+    blocks = DomainBlock.suspend
+    return true if blocks.where(domain: domain).or(blocks.where('domain LIKE ?', "%.#{domain}")).exists?
+
+    if @object
+      context = @object['@context']
+    elsif @json
+      context = @json['@context']
+    else
+      return
+    end
+
+    return unless context
+
+    if context.is_a?(Array)
+      inline_context = context.find { |item| item.is_a?(Hash) }
+      if inline_context
+        keys = inline_context.keys
+        return true if ENV.fetch('REJECT_IF_CONTEXT_EQUALS', '').split.any? { |r| r.in?(keys) }
+        return true if ENV.fetch('REJECT_IF_CONTEXT_STARTS_WITH', '').split.any? { |r| keys.any? { |k| k.start_with?(r) } }
+        return true if ENV.fetch('REJECT_IF_CONTEXT_CONTAINS', '').split.any? { |r| keys.any? { |k| r.in?(k) } }
+      end
+    end
+
+    false
+  end
+
+  def autoreject?(uri = nil)
+    if (@options && @options[:imported]) || should_reject?(uri)
+      Rails.logger.info("Auto-rejected #{@json['type']} activity #{@json['id']}")
+      return true
+    end
+    false
+  end
+end
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index d7a805ab3..fee8fcd25 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::Activity
   include JsonLdHelper
+  include AutorejectHelper
   include Redisable
 
   SUPPORTED_TYPES = %w(Note Question).freeze
@@ -185,37 +186,4 @@ class ActivityPub::Activity
     Rails.logger.info("Rejected #{@json['type']} activity #{@json['id']} from #{@account.uri}#{@options[:relayed_through_account] && "via #{@options[:relayed_through_account].uri}"}")
     nil
   end
-
-  def should_reject?
-    return unless @object
-
-    oid = @json['id']
-    return true if ENV.fetch('REJECT_IF_ID_STARTS_WITH', '').split.any? { |r| oid.start_with?(r) }
-    return true if ENV.fetch('REJECT_IF_ID_CONTAINS', '').split.any? { |r| r.in?(oid) }
-
-    url = object_uri.start_with?('http') ? object_uri : @object['url']
-    return if url.nil?
-
-    domain = url.scan(/[\w\-]+\.[\w\-]+(?:\.[\w\-]+)*/).first
-    blocks = DomainBlock.suspend
-    return true if blocks.where(domain: domain).or(blocks.where('domain LIKE ?', "%.#{domain}")).exists?
-
-    if @object['@context'].is_a?(Array)
-      inline_context = @object['@context'].find { |item| item.is_a?(Hash) }
-      if inline_context
-        keys = inline_context.keys
-        return true if ENV.fetch('REJECT_IF_CONTEXT_EQUALS', '').split.any? { |r| r.in?(keys) }
-        return true if ENV.fetch('REJECT_IF_CONTEXT_STARTS_WITH', '').split.any? { |r| keys.any? { |k| k.start_with?(r) } }
-        return true if ENV.fetch('REJECT_IF_CONTEXT_CONTAINS', '').split.any? { |r| keys.any? { |k| r.in?(k) } }
-      end
-    end
-  end
-
-  def autoreject?
-    if @options[:imported] || should_reject?
-      Rails.logger.info("Auto-rejected #{@json['type']} activity #{@json['id']}")
-      return true
-    end
-    false
-  end
 end
diff --git a/app/services/activitypub/fetch_remote_account_service.rb b/app/services/activitypub/fetch_remote_account_service.rb
index 3c2044941..df1e79d7d 100644
--- a/app/services/activitypub/fetch_remote_account_service.rb
+++ b/app/services/activitypub/fetch_remote_account_service.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::FetchRemoteAccountService < BaseService
   include JsonLdHelper
+  include AutorejectHelper
 
   SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
 
@@ -9,12 +10,14 @@ class ActivityPub::FetchRemoteAccountService < BaseService
   def call(uri, id: true, prefetched_body: nil, break_on_redirect: false, only_key: false)
     return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri)
 
+    return if autoreject?(uri)
     @json = if prefetched_body.nil?
               fetch_resource(uri, id)
             else
               body_to_json(prefetched_body, compare_id: id ? uri : nil)
             end
 
+    return if autoreject?
     return if !supported_context? || !expected_type? || (break_on_redirect && @json['movedTo'].present?)
 
     @uri      = @json['id']
@@ -59,4 +62,8 @@ class ActivityPub::FetchRemoteAccountService < BaseService
   def expected_type?
     equals_or_includes_any?(@json['type'], SUPPORTED_TYPES)
   end
+
+  def object_uri
+    nil
+  end
 end
diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb
index 469821032..42280ad74 100644
--- a/app/services/activitypub/fetch_remote_status_service.rb
+++ b/app/services/activitypub/fetch_remote_status_service.rb
@@ -2,15 +2,19 @@
 
 class ActivityPub::FetchRemoteStatusService < BaseService
   include JsonLdHelper
+  include AutorejectHelper
 
   # Should be called when uri has already been checked for locality
   def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil)
+    return if autoreject?(uri)
+
     @json = if prefetched_body.nil?
               fetch_resource(uri, id, on_behalf_of)
             else
               body_to_json(prefetched_body, compare_id: id ? uri : nil)
             end
 
+    return if autoreject?
     return unless supported_context? && expected_type?
 
     return if actor_id.nil? || !trustworthy_attribution?(@json['id'], actor_id)
@@ -49,4 +53,8 @@ class ActivityPub::FetchRemoteStatusService < BaseService
   def needs_update(actor)
     actor.possibly_stale?
   end
+
+  def object_uri
+    nil
+  end
 end
diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb
index 8cb309e52..3e9a2f02a 100644
--- a/app/services/activitypub/fetch_replies_service.rb
+++ b/app/services/activitypub/fetch_replies_service.rb
@@ -2,6 +2,7 @@
 
 class ActivityPub::FetchRepliesService < BaseService
   include JsonLdHelper
+  include AutorejectHelper
 
   def call(parent_status, collection_or_uri, allow_synchronous_requests = true)
     @account = parent_status.account
@@ -44,6 +45,10 @@ class ActivityPub::FetchRepliesService < BaseService
     # amplification attacks.
 
     # Also limit to 5 fetched replies to limit potential for DoS.
-    @items.map { |item| value_or_id(item) }.reject { |uri| invalid_origin?(uri) }.take(5)
+    @items.map { |item| value_or_id(item) }.reject { |uri| autoreject?(uri) || invalid_origin?(uri) }.take(5)
+  end
+
+  def object_uri
+    nil
   end
 end