Question re: PeerTube's pubkey IDs
-
As part of security checking for incoming events, we check that the
keyId
sent in the HTTP signature is actually owned by the actor that the activity came from. This is to guard against activity spoofing from separate users at the same server (e.g. userB@server
pretends to send aCreate(Note)
from userA@server
).Our check is pretty simple, the
keyId
matched against the public key id as retrieved from the actor.Except it fails for PeerTube because:
- PeerTube's actors all have the
#main-key
suffix on their public key IDs (e.g.https://tilvids.com/accounts/thelinuxexperiment#main-key
) - The HTTP Signature's
keyId
does not include the#main-key
suffix (e.g.https://tilvids.com/accounts/thelinuxexperiment
)
So the key ownership cross-check fails.
I could adjust the logic to strip out the URL's hash, but I was wondering if that was actually secure. I assume this is what is already done since PeerTube successfully federates with other softwares.
- PeerTube's actors all have the
-
@julian iirc, that hash fragment part isn't exactly spec behavior?
-
ideally peertube would use keyId to link to the key and not to the actor, but i would guess that the way that this is handled in other softwares is to implicitly accept both keys and actors. so don't just always strip the hash, but instead only strip it for the initial HTTP GET. maintain the hash when checking for key
id
. but you'll still have to handle the invalid case where the keyId is actually an actor. -
-
Thanks all;
- @[email protected] I wasn't actually sure which spec this was a part of (although to be honest I also wasn't planning on reading through a spec to find out)
- @[email protected] this is for verification on receipt of activity, not for an unsolicited GET from me. Didn't think it was a link to the actor id, but that makes sense!
- @[email protected] yeah origin based security deems it safe, but I don't happen to like that security model, personally. I suppose that is the tradeoff... Plus someone could just assign the same pubkey to every user, rendering the whole exercise moot.
-
-
@julian I think URL comparison should not be done as a string. Like @silverpill said, fragments need to be stripped before comparison, alongside the other usual considerations: normalized query parameters, UTF and case normalization for the hostname, etc
-
I donβt see how same web origin makes this secure again one actor signing an activity for another actor at the same origin (scheme, hostname, port). However, I agree that the workaround/hack for this bug is to strip the fragment, if any, and check if the result is the same as the actor URI specified in the activity.
-
julian:
not for an unsolicited GET from me
sorry, to clarify, i meant the initial HTTP GET of the keyId. meaning that, if the keyId contains a fragment component, you perform the HTTP GET against the keyId minus the fragment component.
-
>I donβt see how same web origin makes this secure again one actor signing an activity for another actor at the same origin (scheme, hostname, port).
Because only location of a key matters. This is specified in FEP-fe34, and I just published a more detailed explanation of how it all works:
-
silverpill1:
... only location of a key matters. This is specified in FEP-fe34, and I just published a more detailed explanation of how it all works:
After rereading that FEP, I think I understand better why we have different perspectives on this topic. First, "web origin" is not the same as the AP "same origin policy" described in the non-normativeAP authz/authn primer. These two kinds of "origins" are not computed with the "same algorithm" as claimed by the FEP (or at least it appears to me that this is the claim, it's not completely clear). In this thread, it seems to me that you are using "origin" in the "web origin" sense. If not, please clarify what you mean.
The other issue is that the FEP doesn't appear to be consistent with the W3C SocialCG group report on HTTP Signatures. This document describes an algorithm for verifying an actor/key relationship that does not depend on (or require) either the same web origin for actors and keys or the AP same origin policy. The AP "same origin policy" appears to be described in an authorization policy context rather than for HTTP signature authentication.
The inconsistency I see is that the FEP requires "embedded" objects to have same web (?) origin as the containing object. Keys may or may not be embedded as part of the serialized actor graph. They may only be referenced by URI (even Mastodon supports it), but if they happen to be embedded in the actor graph serialization, I know of no good reason to apply the FEP origin-related constraints to the URIs.
What's important for verifying the actor/key relationship is the mutual references between the actor
publicKey
and the key'sowner
(orcontroller
) property. The key itself could be served from a different web origin than the actor document. Furthermore, there's no guarantee that removing the key's URI fragment, if any, will lead to successfully verifying the actor/key relationship, even if the relationship is valid. For example:key URI:
https://keyserver.example/bob/keychain#B54F15A0
actor URI:https://server.example/bob
As long as, the document retrieved from
https://server.example/bob
has apublicKey
property referring to the key URI and the key object has anowner
orcontroller
property referring to the actor URI, it's a valid relationship.In other words, removing or ignoring the key URI fragment will not generally work. In this example, dereferencing the key URI might result in a key chain object with several public keys having different fragment identifiers. Even more conventional AP actor documents might have multiple public keys with different fragment identifiers (mentioned in the SocialCG report). Ignoring key URI fragments will not work in this case either.
-
@stevebate I'm using the term "origin" as defined in RFC-6454. This is also what FEP-fe34 refers to.
FEP-fe34 doesn't require embedded object to have same origin as the containing object (but it says that embedded object with a different origin shouldn't be trusted).
FEP-fe34 doesn't mention actor/key relationship because location of an actor document is not important for authentication via HTTP signatures. Only location of a key is important.
However, the actor/key relationship is important for authorization: "Can that actor own this public key?". FEP-fe34 currently doesn't provide a direct answer to this question, but it recommends the same origin policy as a general principle. According to this principle, actors shouldn't own objects on different servers, and therefore public key should have same origin as actor. As far as I know, all existing implementations behave in this way and don't put public key on a different server than actor. I also don't see any reason to do otherwise.
If some document contradicts both FEP-fe34 and implementer consensus, it is probably not correct and should be fixed. I can look into it if you point to a specific paragraph or sentence.