Fix ActivityPub fetch sanitisation #1018

Merged
Oneric merged 5 commits from Oneric/akkoma:fix-fetch-serve-sanitisation into develop 2025-11-24 00:35:24 +00:00
Owner

Blergh; see commit messages for details.

For better future bisectability and to have a easily and neraly risk-free backportable change for the most pressing thing here I opted to first just apply a minimal fix and then later replace fetch’s bespoke sanitisation with the better tested Transmogrifier sanitisation pipeline

Fixes #1017 (though interop issues are the least problematic part here)

Blergh; see commit messages for details. For better future bisectability and to have a easily and neraly risk-free backportable change for the most pressing thing here I opted to first just apply a minimal fix and then later replace fetch’s bespoke sanitisation with the better tested Transmogrifier sanitisation pipeline Fixes #1017 (though interop issues are the least problematic part here)
When the object associated with the activity was preloaded
(which happens automatically with Activity.normalize used in the
 controller) Object.normalize’s "id_only" option did not actually work.
This option and it’s usage were introduced to fix display of Undo
activities in e88f36f72b.
For "Undo"s (and "Delete"s) there is no object preloaded
(since it is already gone from the database) thus this appeared
to work and for the particular case considered there in fact did.
Create activities use different rendering logic and thus remained
unaffected too.

However, for all other types of Activities (yes, including Update
which really _should_ include a properly sanitised, full object)
this new attempt at including "just the id", lead to it instead
including the full, unsanitised data of the referenced object.

This is obviously bad and can get worse due to access restrictions
on the activity being solely performed based on the addressing
of the activity itself, not of the (unintentionally) embedded
object.

Starting with the obvious, this leaks all "internal" fields
but as already mentioned in 8243fc0ef4
all current "internal" fields from Constants.object_internal_fields
are already publicised via MastoAPI etc anyway. Assuming matching
addressing of the referenced object and activity this isn't problematic
with regard to confidentiality.
Except, the internal "voters" field recording who voted for a poll
is currently just omitted from Constants.object_internal_fields
and indeed confidential information (fix in subsequent commit).
Fortunately this list is for the poll as a whole and there are no
inlined lists for individual choices. While this thus leaks _who_
voted for a poll, it at least doesn't directly expose _what_ each voter
chose if there are multiple voters.

As alluded to before, the access restriction not being aware
of the misplaced object data into account makes the issue worse.
If the activity addressing is not a subset of the referenced object’s
addressing, this will leak private objects to unauthorised users.
This begs the question whether such mismatched addressing can occur.
For remote activities the answer is ofc a resounding YES,
but we only serve local ActivityPub objects and for the latter
it currently(!) seems like a "no".
For all intended interactions, the user interacting must already have
access to the object of interest and our ActivityPub Builder
already uses a subset of the original posts addressing for
posts not publicly accessible. This addressing creation logic
was last touched six years ago predating the introduction of this
exposure blunder.
The rather big caveat her being, until it was fixed just yesterday in
dff532ac72 it was indeed possible to
interact with posts one is not allowed to actually see. Combined, this
allowed unauthorised access to private posts. (The API ID of such
private posts can be obtained e.g. from replies one _is_ allowed to see)

During the time when ActivityPub C2S was supported there might have been
more ways to create activities with mismatched addressing and sneak a
peek on private posts. (The AP id can be obtained in an analogous way)

Replaces and fixes e88f36f72b.
Since there never were any users of the
bugged "id_only" option it is removed.

This was reported by silverpill <silverpill@firemail.cc> as an
ActivityPub interop issue, since this blunder of course also
leads to invalid AP documents by adding an additional layer
in form of the "data" key and directly exposing the internal
Pleroma representation which is not always identical to valid AP.

Fixes: #1017
It is inlined and used to keep track of who already voted for a poll.
This is expected to be confidential information and must no be exposed
Duped code just means double the chance to mess up. This would have
prevented the leak of confidential info more minimally fixed in
6a8b8a14999f3ed82fdaedf6a53f9a391280df2f and  now furthermore
fixes the representation of Update activites which _need_ to have their
object inlined, as well as better interop for follow Accept and Reject
activities and all other special cases already handled in Transmogrifier.
It also means we get more thorough tests for free.

This also already adds JSON-LD context and does not add bogus Note-only
fields as happened before due to this views misuse of prepare_object
for activities. The doc of prepare_object clearly states it is only
intended for creatable objects, i.e. (for us) Notes and Questions.
test: add more representation tests for perpare_outgoing
Some checks failed
ci/woodpecker/pr/test/2 Pipeline was successful
ci/woodpecker/pr/test/1 Pipeline failed
272799da62
In particular this covers the case
e88f36f72b was meant to fix and
the case from #1017
Author
Owner

The CI failures of the elixir 1.14 job is just due to three known-flaky cases plus the recent issue of sometimes no retry of failed flaky tests being attempted

The CI failures of the elixir 1.14 job is just due to three known-flaky cases plus the recent issue of sometimes no retry of failed flaky tests being attempted
Oneric merged commit f5d78b374c into develop 2025-11-24 00:35:24 +00:00
Oneric deleted branch fix-fetch-serve-sanitisation 2025-11-24 00:35:25 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
AkkomaGang/akkoma!1018
No description provided.