Do not serve account actors at all in limited federation mode (#14800)

* Do not serve account actors at all in limited federation mode

When an account is fetched without a signature from an allowed instance,
return an error.

This isn't really an improvement in security, as the only information that was
previously returned was required protocol-level info, and the only personal bit
was the existence of the account. The existence of the account can still be
checked by issuing a webfinger query, as those are accepted without signatures.

However, this change makes it so that unallowed instances won't create account
records on their end when they find a reference to an unknown account.

The previous behavior of rendering a limited list of fields, instead of not
rendering the actor at all, was in order to prevent situations in which two
instances in Authorized Fetch mode or Limited Federation mode would fail to
reach each other because resolving an account would require a signed query…
from an account which can only be fetched with a signed query itself. However,
this should now be fine as fetching accounts is done by signing on behalf of
the special instance actor, which does not require any kind of valid signature
to be fetched.

* Fix tests
This commit is contained in:
ThibG 2020-09-14 13:04:29 +02:00 committed by GitHub
parent 42c4322ce7
commit cd4ec7cd74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 4 additions and 27 deletions

View File

@ -7,6 +7,7 @@ class AccountsController < ApplicationController
include AccountControllerConcern include AccountControllerConcern
include SignatureAuthentication include SignatureAuthentication
before_action :require_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
before_action :set_cache_headers before_action :set_cache_headers
before_action :set_body_classes before_action :set_body_classes
@ -48,7 +49,7 @@ class AccountsController < ApplicationController
format.json do format.json do
expires_in 3.minutes, public: !(authorized_fetch_mode? && signed_request_account.present?) expires_in 3.minutes, public: !(authorized_fetch_mode? && signed_request_account.present?)
render_with_cache json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter, fields: restrict_fields_to render_with_cache json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter
end end
end end
end end
@ -153,12 +154,4 @@ class AccountsController < ApplicationController
def params_slice(*keys) def params_slice(*keys)
params.slice(*keys).permit(*keys) params.slice(*keys).permit(*keys)
end end
def restrict_fields_to
if signed_request_account.present? || public_fetch_mode?
# Return all fields
else
%i(id type preferred_username inbox public_key endpoints)
end
end
end end

View File

@ -348,24 +348,8 @@ RSpec.describe AccountsController, type: :controller do
context 'in authorized fetch mode' do context 'in authorized fetch mode' do
let(:authorized_fetch_mode) { true } let(:authorized_fetch_mode) { true }
it 'returns http success' do it 'returns http unauthorized' do
expect(response).to have_http_status(200) expect(response).to have_http_status(401)
end
it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json'
end
it_behaves_like 'cachable response'
it 'returns Vary header with Signature' do
expect(response.headers['Vary']).to include 'Signature'
end
it 'renders bare minimum account' do
json = body_as_json
expect(json).to include(:id, :type, :preferredUsername, :inbox, :publicKey)
expect(json).to_not include(:name, :summary)
end end
end end
end end