diff options
author | Claire <claire.github-309c@sitedethib.com> | 2023-02-10 22:16:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-10 22:16:37 +0100 |
commit | 0c9eac80d887cdf7f1efa582b21006248d2f83eb (patch) | |
tree | 208ac4a6745b34f45e5d69b96262ce92aa59c59f /spec/services/activitypub | |
parent | 719bb799be9a03b767bd9f55d30abf2b7bc318ec (diff) |
Fix unbounded recursion in post discovery (#23506)
* Add a limit to how many posts can get fetched as a result of a single request * Add tests * Always pass `request_id` when processing `Announce` activities --------- Co-authored-by: nametoolong <nametoolong@users.noreply.github.com>
Diffstat (limited to 'spec/services/activitypub')
-rw-r--r-- | spec/services/activitypub/fetch_remote_status_service_spec.rb | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/spec/services/activitypub/fetch_remote_status_service_spec.rb b/spec/services/activitypub/fetch_remote_status_service_spec.rb index 7359ca0b4..a81dcad81 100644 --- a/spec/services/activitypub/fetch_remote_status_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_status_service_spec.rb @@ -223,4 +223,98 @@ RSpec.describe ActivityPub::FetchRemoteStatusService, type: :service do end end end + + context 'statuses referencing other statuses' do + before do + stub_const 'ActivityPub::FetchRemoteStatusService::DISCOVERIES_PER_REQUEST', 5 + end + + context 'using inReplyTo' do + let(:object) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/1", + type: 'Note', + content: 'Lorem ipsum', + inReplyTo: 'https://foo.bar/@foo/2', + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + } + end + + before do + 8.times do |i| + status_json = { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/#{i}", + type: 'Note', + content: 'Lorem ipsum', + inReplyTo: "https://foo.bar/@foo/#{i + 1}", + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + to: 'as:Public', + }.with_indifferent_access + stub_request(:get, "https://foo.bar/@foo/#{i}").to_return(status: 200, body: status_json.to_json, headers: { 'Content-Type': 'application/activity+json' }) + end + end + + it 'creates at least some statuses' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2) + end + + it 'creates no more account than the limit allows' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5) + end + end + + context 'using replies' do + let(:object) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/1", + type: 'Note', + content: 'Lorem ipsum', + replies: { + type: 'Collection', + id: 'https://foo.bar/@foo/1/replies', + first: { + type: 'CollectionPage', + partOf: 'https://foo.bar/@foo/1/replies', + items: ['https://foo.bar/@foo/2'], + }, + }, + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + } + end + + before do + 8.times do |i| + status_json = { + '@context': 'https://www.w3.org/ns/activitystreams', + id: "https://foo.bar/@foo/#{i}", + type: 'Note', + content: 'Lorem ipsum', + replies: { + type: 'Collection', + id: "https://foo.bar/@foo/#{i}/replies", + first: { + type: 'CollectionPage', + partOf: "https://foo.bar/@foo/#{i}/replies", + items: ["https://foo.bar/@foo/#{i+1}"], + }, + }, + attributedTo: ActivityPub::TagManager.instance.uri_for(sender), + to: 'as:Public', + }.with_indifferent_access + stub_request(:get, "https://foo.bar/@foo/#{i}").to_return(status: 200, body: status_json.to_json, headers: { 'Content-Type': 'application/activity+json' }) + end + end + + it 'creates at least some statuses' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_least(2) + end + + it 'creates no more account than the limit allows' do + expect { subject.call(object[:id], prefetched_body: Oj.dump(object)) }.to change { sender.statuses.count }.by_at_most(5) + end + end + end end |