Question re: Origin Based Security Model (FEP-fe34)

I received a security vulnerability report regarding NodeBB's handling of Update and Delete activities.

tl;dr

  • NodeBB implementes FEP fe34, and treats Update and Delete activities as valid if the activity's actor and the object's attributedTo differ but the origins are identical.
  • e.g. @[email protected] is allowed to federate Delete(Note) on @[email protected]'s Note.
  • The origin-based security model allows for moderator-style actions (third-party post editing and deletions) in the absence of explicit moderator claims.
  • The reporter disagrees that this should be allowed.

Are they right? [...]

https://activitypub.space/post/1919

Question re: Origin Based Security Model (FEP-fe34)

I received a security vulnerability report regarding NodeBB's handling of Update and Delete activities. tl;dr NodeBB implementes FEP fe34, and treats Update...

⁂ ActivityPub.Space

My thoughts:

I don't necessarily think FEP fe34 is strict enough to be a guiding principle for security across federated instances. The reporter said:

"at minimum" means same-origin is the floor, not the ceiling.

... and he's right, there's more you should do to verify that only the owner or a designated moderator can update and delete an object.

However we don't have a widely-used ability to determine who the moderators or admins are for any given instance. Mastodon may have an endpoint (in their API), threadiverse software use their own (as directed by 1b12, and even then it's optional), other software  ?

So we fall back to origin-based security model and hand off the responsibility of determining who can and cannot alter somebody else's objects to the sending server.

That's a risk we take with this model. Not sure if there is more that can be done to tighten this up.

@julian You're making a very strong assumption that the remote server is necessarily checking for things it might not actually be checking for.

Neither the "instance" model nor the "same origin" model are enshrined in ActivityPub. This technically falls under "undefined behavior", because AP doesn't define an authorization model. (It suggests ("may") same origin, but that's about it. A lot of things are "at the receiving server's discretion".)

@[email protected] on the flip side, I could argue that if the sending server doesn't enforce boundaries between actors, then there's no need to enforce the boundary on my end.

For example, if the sending server is a federated wiki where anyone™️ can edit, then it would actually be incorrect for me to enforce a boundary.

@julian The sending server might not have boundaries to enforce. Especially not along "same origin" lines. This requires agreement on what the authorization model is.

Say for example everyone gets a subdirectory that they "own" -- /~alice/ and /~bob/ have their spaces on the same origin. One authorization model is "anything within this container is authorized". If you don't recognize this, you can't detect that alice and bob have a boundary between them.

@julian Really, taking "same origin" to its logical conclusion would mean that every actor MUST have their own origin and therefore their own FQDN. It doesn't make sense for origins hosting user-generated content unless the UGC is very tightly controlled and sanitized. And even that's not a guarantee of safety.
@julian oh dear, these couple of mentions seem not to have made it across. do i need to also mention @technical-discussion too?
@[email protected] ...! That sounds like a bug. They all came in after you mentioned the category.
@trwnh @julian I would be more comfortable with there being a way of the serving server explicitly saying "this actor is allowed to moderate"

@Profpatsch @julian i've been doing some trust and safety TF work to explore/develop a bidirectional link between actors and moderators/hosts, yeah. mostly in the context of "where to send moderation related activities" (so you don't Flag a user to themselves if there's a better option), but also could be used for authorizing Update/Delete activities.

alternatively, the problem would not be there if service actors messaged each other for more explicit syndication...

I agree out of principle that the security implications exist, but if you follow through with the exploit, it requires a non-compliant server to allow users to publish Update and Delete for other users on the same instance, and even then the exposure is limited to users of that origin only (e.g. your server cannot arbitrarily delete my posts). This is the foundation of the Origin-based security model.

Correct. FEP-fe34 is based on the assumption that originating servers enforce boundaries between actors. This is stated in the section "Assumptions":

The origin-based security model is designed for use in a network where a server is resposible for enforcing security boundaries between the hosted actors. Servers that publish objects without validation are not supported.

In some cases, FEP-fe34 recommends same-actor policy as an additional protection against implementation bugs and against implementations that don't enforce actor boundaries on purpose. Update/Delete authorization is one of those cases (admittedly, the wording is a bit confusing in that paragraph...)

Is the assumption on which FEP-fe34 is based valid?

Of course, it is primarily a philosophical question. Who should be responsible for enforcing boundaries between actors hosted on the same server, the sender or the recipient? In my opinion, the answer is clear: the sender should be responsible.

As far as I know, the majority of existing implementations do enforce boundaries between actors. I am not aware of any implementation that doesn't do that.

Enforcement of boundaries is challenge for generic ActivityPub servers, but it's not insurmountable.

fep/fep/fc48/fep-fc48.md at main

fep - Fediverse Enhancement Proposals

Codeberg.org

@[email protected] said:

In some cases, FEP-fe34 recommends same-actor policy as an additional protection against implementation bugs and against implementations that don't enforce actor boundaries on purpose. Update/Delete authorization is one of those cases (admittedly, the wording is a bit confusing in that paragraph...)

Does this mean NodeBB is wrong is allowing different actors on the same origin to publish Updates and Deletes? I do not know of a way to reconcile this with the ability to have moderators carry out their actions.

⁂ ActivityPub.Space

⁂ ActivityPub.Space

No, it's not wrong.

I think the good of group moderation currently outweighs the theoretical bad of same-origin impersonation.

@julian I've done a review on FEP-fe34 and here's a more nuanced answer.

The same-origin assumption is necessary for authentication, because it is not possible to not trust the server of origin.

But it is not necessary for authorization. It is desirable, because that makes authorization procedures aligned with authentication procedures. But we can shift the burden of permission checks to the recipient.

We might even have to do this, if we discover that servers accepting arbitrary payloads (C2S, FEP-ae97) can't reliably enforce the isolation of actors.

But for the time being, you can accept same-origin admin deletions.

@julian @silverpill we did not define this well in ActivityPub.

There's an implicit authorization model (creator can write the object, addressees can read and react) which will probably be more explicit in the next version, but we'd leave open other types of authorization.

I think it's likely in the future we'll have a property for defining additional access control options.

Same-origin is a good guess but it's not as good as explicit properties.

We also got the same type of vulnerability reports. Good that you bring it up, because I wasnt aware of the FEP.

To answer your question we can look at it the other way. Imagine we implement a way to federate admin/moderator status and then check it for every incoming mod action. First of all we get problems with older platforms which dont implement this feature yet, it means all their mod actions will be rejected and we end up with spam. Or we add a way to bypass the check, then the whole security feature becomes pointless.

Even if we assume that all platforms correctly federate the admin/mod status, there would still be problems. Federation is not perfect, sometimes things get lost. Or someone gets appointed as admin and immediately removes some spam. At this point the admin status is not federated yet (if its part of the user profile and only updated every 24h). Then again valid mod actions are rejected and we end up with spam that is not deleted.

On the other hand, whats exactly is the exploit here? Some platform lets a normal user (no admin/mod rights) send Update or Delete activites for another user on the same instance. That is clearly not our problem, but its a problem of the remote platform which allows such actions. Besides it cannot affect users from other instances so the impact would be very limited.

Overall, adding such stricter checks would create more problems than it solves.

@julian said:

A strict reading of this does not preclude the ability of a same-origin moderator to modify and delete the object. This is my argument.

I think I'd ask here is why is the Delete/Update coming from the moderator, instead of from the account that posted the thing, since that account is the owner of that thing?

Edit: For the moderation use case, I believe Moderation Actors will be the answer here.

Question re: Origin Based Security Model (FEP-fe34)

I received a security vulnerability report regarding NodeBB's handling of Update and Delete activities. tl;dr NodeBB implementes FEP fe34, and treats Update...

⁂ ActivityPub.Space

@thisismissem isn't that the correct way to communicate this across the wire?

The moderator is deleting the post, not the author, so the moderator is the Delete's actor.

You could fake this by federating out an update or delete as though it came from the original author, which would be a most compatible way to do things, but it isn't necessarily right.

@julian yeah, but the problem with the same-origin model is that you don't know who the moderator is. the actor https://social.example/joe shouldn't be able to delete https://social.example/steve's posts or issue updates. But if steve is moderatedBy https://social.example/mods, then a Delete or Update from https://social.example/mods for https://social.example/steve

So whilst you have same-origin, you actually also have same-actor and http-message-signatures indicated authenticated actor.

@thisismissem Yes, agreed. However in the absence of any widespread consensus on how exactly to do that, the current origin-based security model is all we've got.

Open to working on standardizing that though 

Well, yeah, that's why I linked what T&S is doing here to fix the moderator use case. At present I don't know of anyone sending cross-actor delete/update actions, so we'd be adding capability with the moderatedBy

@thisismissem hmm, I believe Lemmy and Piefed send cross actor Deletes, but they might be Announces by the group actor.

They (and I) don't use moderatedBy but rather the group actor's attributedTo

Just want to make sure you're aware of that existing prior art.

@[email protected] @[email protected] @[email protected] — do y'all send Delete activities with the moderator actor?

(Announce wrapping aside.)

Yes.

This is easy in FEP 1b12-land because each community has a list of moderators so receiving instances know who to allow.

Getting a list of instance admins requires calling the Lemmy API, unfortunately. So PieFed has a cron job that does that once per day for all instances. Admins rarely change.

@[email protected] said:

Getting a list of instance admins requires calling the Lemmy API, unfortunately.

Wait, why don't we write a mini FEP to extend this? attributedTo on the instance/application actor?

⁂ ActivityPub.Space

⁂ ActivityPub.Space

That sounds fine to me.

On communities the moderators are just an array of strings which are the activitypub actor IDs of the mods. I think NodeBB has an array of actor objects though?

Anyway whatever it is, consistency with how the communities do it would be nice.

@[email protected] said:

I think NodeBB has an array of actor objects though

Is this causing problems for you? I can send just the IDs instead.

⁂ ActivityPub.Space

⁂ ActivityPub.Space
It’s fine, I’ve already adjusted the code at my end. I don’t know about Lemmy though.
lemmy/crates/apub/apub/assets/lemmy/collections/group_moderators.json at main · LemmyNet/lemmy

🐀 A decentralised discussion platform for communities. - LemmyNet/lemmy

GitHub

Right, that's the "Group Moderation" section of FEP 1b12, right?

It may be a good idea to extend this concept to the instance/application actor as well. There's no urgent need to implement and consume, but it would be fairly simple thing to serve on our respective softwares I think.

Yes exactly that FEP. Federating admin status would make sense for informational purposes, but rejecting mod actions based on that could cause problems as I mentioned in my previous comment.

@[email protected] said:

but rejecting mod actions based on that could cause problems as I mentioned in my previous comment.

So to confirm then, you serve the moderator collection but you don't use it to determine whether an actor is able to modify/delete content on that instance, is that right?

Curious to know what those problems are.

⁂ ActivityPub.Space

⁂ ActivityPub.Space
We use the moderator collection. But if that fails we check if the mod is from the same instance as the community or the post/comment being removed. If thats true we also allow the action.

Understood, so the mod check is done but also accepts origin-based security as per fe34.

That actually does make sense and allows for cross-origin moderation.

Sorry @julian and @[email protected] if this has almost nothing to do with this, but I'd like to point out that Lemmy (perhaps Piefed as well, but I'm not sure) has a very interesting feature: a community moderator can also be a user of an instance other than the one where that community is physically located.
This isn't possible with NodeBB because the API call isn't considered valid.
This means that the Lemmy development staff has managed to develop a way to somehow federate content moderation.
@julian @rimu Do you want specifically FEP-2677? Please consider using FEP-d556 instead, it is very similar to FEP-2677 but doesn't require NodeInfo. Also, it is FINAL.
fep/fep/d556/fep-d556.md at main

fep - Fediverse Enhancement Proposals

Codeberg.org
@[email protected] was not aware of d556. I'll make the swap, thanks.
Lemmy doesnt even federate admin status in any way, instead we trust that actions which are coming from the same instance as the community or post are valid. So essentially origin-based security model.

@julian @thisismissem @technical-discussion Note that a community's attributedTo doesn't work for anything outside of communities, but a moderator can be declared for any object.

Right now, attributedTo.inbox is the last option to send your moderation activities. There are probably more relevant options to try first. The work is to identify those options and make them consistently discoverable. See "Delegated control" here: https://github.com/swicg/activitypub-trust-and-safety/issues/24#issuecomment-4365331657