From 86f29a68fbf5344291b21253f597a914cec18f02 Mon Sep 17 00:00:00 2001 From: multiple creatures Date: Mon, 22 Jul 2019 20:04:15 -0500 Subject: [PATCH] allow autorejecting incoming ap activities by `id`, `@context`, and domain + autoject suspended domains & their subdomains --- app/lib/activitypub/activity.rb | 33 ++++++++++++++++++++++++ app/lib/activitypub/activity/accept.rb | 1 + app/lib/activitypub/activity/add.rb | 1 + app/lib/activitypub/activity/announce.rb | 1 + app/lib/activitypub/activity/create.rb | 1 + app/lib/activitypub/activity/flag.rb | 1 + app/lib/activitypub/activity/follow.rb | 1 + app/lib/activitypub/activity/like.rb | 1 + app/lib/activitypub/activity/move.rb | 1 + app/lib/activitypub/activity/update.rb | 1 + 10 files changed, 42 insertions(+) diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index c73b2c4f5..d7a805ab3 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -185,4 +185,37 @@ 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/lib/activitypub/activity/accept.rb b/app/lib/activitypub/activity/accept.rb index 348ee0d1c..525d4ffd6 100644 --- a/app/lib/activitypub/activity/accept.rb +++ b/app/lib/activitypub/activity/accept.rb @@ -11,6 +11,7 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity private def accept_follow + return if autoreject? return accept_follow_for_relay if relay_follow? target_account = account_from_uri(target_uri) diff --git a/app/lib/activitypub/activity/add.rb b/app/lib/activitypub/activity/add.rb index 688ab00b3..d9ff9c5b9 100644 --- a/app/lib/activitypub/activity/add.rb +++ b/app/lib/activitypub/activity/add.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Add < ActivityPub::Activity def perform + return if autoreject? return unless @json['target'].present? && value_or_id(@json['target']) == @account.featured_collection_url status = status_from_uri(object_uri) diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 99807d963..ada46b378 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def perform + return if autoreject? return reject_payload! if !@options[:imported] && (delete_arrived_first?(@json['id']) || !related_to_local_activity?) original_status = status_from_object diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index beef93e5a..94cde4bd6 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def perform + return if autoreject? return reject_payload! if unsupported_object_type? || !@options[:imported] && (invalid_origin?(@object['id']) || Tombstone.exists?(uri: @object['id']) || !related_to_local_activity?) RedisLock.acquire(lock_options) do |lock| diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb index f73b93058..7fb6e3422 100644 --- a/app/lib/activitypub/activity/flag.rb +++ b/app/lib/activitypub/activity/flag.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity def perform + return if autoreject? return if skip_reports? target_accounts = object_uris.map { |uri| account_from_uri(uri) }.compact.select(&:local?) diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb index 1e805c0d1..84041ec8d 100644 --- a/app/lib/activitypub/activity/follow.rb +++ b/app/lib/activitypub/activity/follow.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity def perform + return if autoreject? target_account = account_from_uri(object_uri) return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id']) || @account.requested?(target_account) diff --git a/app/lib/activitypub/activity/like.rb b/app/lib/activitypub/activity/like.rb index 674d5fe47..2c4a9d805 100644 --- a/app/lib/activitypub/activity/like.rb +++ b/app/lib/activitypub/activity/like.rb @@ -2,6 +2,7 @@ class ActivityPub::Activity::Like < ActivityPub::Activity def perform + return if autoreject? original_status = status_from_uri(object_uri) return if original_status.nil? || !original_status.account.local? || delete_arrived_first?(@json['id']) || @account.favourited?(original_status) diff --git a/app/lib/activitypub/activity/move.rb b/app/lib/activitypub/activity/move.rb index d7a5f595c..b1c986551 100644 --- a/app/lib/activitypub/activity/move.rb +++ b/app/lib/activitypub/activity/move.rb @@ -4,6 +4,7 @@ class ActivityPub::Activity::Move < ActivityPub::Activity PROCESSING_COOLDOWN = 7.days.seconds def perform + return if autoreject? return if origin_account.uri != object_uri || processed? mark_as_processing! diff --git a/app/lib/activitypub/activity/update.rb b/app/lib/activitypub/activity/update.rb index 70035325b..8fb48e073 100644 --- a/app/lib/activitypub/activity/update.rb +++ b/app/lib/activitypub/activity/update.rb @@ -4,6 +4,7 @@ class ActivityPub::Activity::Update < ActivityPub::Activity SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze def perform + return if autoreject? if equals_or_includes_any?(@object['type'], SUPPORTED_TYPES) update_account elsif equals_or_includes_any?(@object['type'], %w(Question))