10
45
Fork
You've already forked doipjs
28

Verification of delegated ActivityPub profiles #98

Open
opened 2024年04月07日 07:15:47 +02:00 by cuteBoiButt · 1 comment

"Delegated" in the same sense that matrix uses it, for example, here: https://matrix-org.github.io/synapse/latest/delegate.html
(hosting on sub.example.tld while preserving federated @username@example.tld usernames)

Digging through the code, it seems like doipjs does not perform any WebFinger requests for AP validation at all, which means it will fail to validate https://example.tld/@username AP claims for delegated profiles cuz there is just nothing there, actual profile is hosted on a different (sub)domain.
Is there any specific reason as to why no WebFinger request is performed for AP validation if initial attempt to locate profile at provided url fails?

Example of a failed validation: https://keyoxide.org/hkp/61ADEA93AEEC0534176B36494C82DB4C8F1BA6FA

My setup looks like this:
i have a 301 redirect for both webfinger and nodeinfo endpoints pointing to the subdomain hosting AP capable software, like so:
example.tld/.well-known/webfinger 301 => sub.example.tld/.well-known/webfinger
example.tld/.well-known/nodeinfo 301 => sub.example.tld/.well-known/nodeinfo

sub.example.tld/.well-known/webfinger endpoint will return { subject: "acct:username@example.tld", ... } when looking up either acct:username@example.tld or acct:username@sub.example.tld which allows to establish a two-way relationship between example.tld and sub.example.tld in order to prevent any hijacking by a malicious 3rd party.

I know this approach is not standardized, but this appears to be the only way to achieve delegation atm.
And it seems to be enough for other popular AP-capable software, namely Mastodon, to correctly recognize delegated profiles "hosted" on @example.tld and properly federate with them.
(try looking up @cuteBoiButt@torchmc.ru on your favorite Mastodon instance to see this in action :з)

I can try to cook up a pr improving AP validation to support such setups if there are no objections ^.^

"Delegated" in the same sense that matrix uses it, for example, here: https://matrix-org.github.io/synapse/latest/delegate.html (hosting on `sub.example.tld` while preserving federated `@username@example.tld` usernames) Digging through the code, it seems like doipjs does not perform any WebFinger requests for AP validation at all, which means it will fail to validate `https://example.tld/@username` AP claims for delegated profiles cuz there is just nothing there, actual profile is hosted on a different (sub)domain. Is there any specific reason as to why no WebFinger request is performed for AP validation if initial attempt to locate profile at provided url fails? Example of a failed validation: https://keyoxide.org/hkp/61ADEA93AEEC0534176B36494C82DB4C8F1BA6FA My setup looks like this:  i have a 301 redirect for both webfinger and nodeinfo endpoints pointing to the subdomain hosting AP capable software, like so:   `example.tld/.well-known/webfinger` 301 => `sub.example.tld/.well-known/webfinger`   `example.tld/.well-known/nodeinfo` 301 => `sub.example.tld/.well-known/nodeinfo` `sub.example.tld/.well-known/webfinger` endpoint will return `{ subject: "acct:username@example.tld", ... }` when looking up either `acct:username@example.tld` or `acct:username@sub.example.tld` which allows to establish a two-way relationship between `example.tld` and `sub.example.tld` in order to prevent any hijacking by a malicious 3rd party. I know this approach is not standardized, but this appears to be the only way to achieve delegation atm. And it seems to be enough for other popular AP-capable software, namely Mastodon, to correctly recognize delegated profiles "hosted" on `@example.tld` and properly federate with them. (try looking up `@cuteBoiButt@torchmc.ru` on your favorite Mastodon instance to see this in action :з) I can try to cook up a pr improving AP validation to support such setups if there are no objections ^.^

I can try to cook up a pr improving AP validation to support such setups if there are no objections ^.^

Did you find any time to take a look at this?

I think I've seen this issue before but can't find it. The main problem is that there is no official/proper way to reverse engineer a webfinger endpoint or acct from an ActivityPub actor uri - which is what you add to your PGP key. There is an upstream bug in the Mastodon repo that talks about solutions for this but it's not gone anywhere.

From keyoxides point of view the only way to do this right now is to brute force the checks i.e. keep trying subdomains until the webfinger attempts fail or you run out of them. But that doesn't cover the possibility that your handle exists on a completely different domain (which is allowed). That said that could be exceedingly rare.

A possible pseudo algorithm could be:

  1. Access https://social.services.example.com/users/actor
  2. Find Mastodon/ActivityPub profile
  3. Derive and access https://social.services.example.com/.well-known/webfinger?resource=acct:actor@social.services.example.com
    a) It specifies the 'subject' as 'acct:actor@example.com'
  4. Derive and access https://example.com/.well-known/webfinger?resource=acct:actor@example.com
  5. Verify it matches the response of 3) and contains the URI of 1)

As I've said though, deriving the URL in 3) from the profile URI of 1) is the tricky part and would mostly just be guesswork on keyoxides part.

EDIT
That said, having now looked at the code, some derivation work is already being done in the implementation to get display name. It shouldn't be too hard to implement the above using that information.

> I can try to cook up a pr improving AP validation to support such setups if there are no objections ^.^ Did you find any time to take a look at this? I think I've seen this issue before but can't find it. The main problem is that there is no official/proper way to reverse engineer a webfinger endpoint or acct from an ActivityPub actor uri - which is what you add to your PGP key. There is an upstream bug in the Mastodon repo that talks about solutions for this but it's not gone anywhere. From keyoxides point of view the only way to do this right now is to brute force the checks i.e. keep trying subdomains until the webfinger attempts fail or you run out of them. But that doesn't cover the possibility that your handle exists on a completely different domain (which is allowed). That said that could be exceedingly rare. A possible pseudo algorithm could be: 1) Access https://social.services.example.com/users/actor 2) Find Mastodon/ActivityPub profile 3) Derive and access https://social.services.example.com/.well-known/webfinger?resource=acct:actor@social.services.example.com a) It specifies the 'subject' as 'acct:actor@example.com' 5) Derive and access https://example.com/.well-known/webfinger?resource=acct:actor@example.com 6) Verify it matches the response of 3) and contains the URI of 1) As I've said though, deriving the URL in 3) from the profile URI of 1) is the tricky part and would mostly just be guesswork on keyoxides part. EDIT That said, having now looked at the code, some derivation work is already being done in the implementation to get display name. It shouldn't be too hard to implement the above using that information.
Sign in to join this conversation.
No Branch/Tag specified
main
dev
fix-irc-fetcher
new-claim-eveonline-143
prepare-new-release
fix-jsdoc-types
yarn-to-npm
support-openpgp-aspe-claims
support-html-alias
improve-activitypub-support
v1-restructure
into-es-module
support-aspe
fix-js-lsp-issues
improve-linting
add-markers
support-opencollective-claim
support-entity-decoding
use-rome-tools
support-cloudflare-buster
support-fediverse-posts
matrix-room-verification
2.1.0
2.1.0-rc.3
2.1.0-rc.2
2.1.0-rc.1
2.0.1
2.0.0
2.0.0-rc.1
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.1.1
1.1.0
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
v0.19.1-alpha.0
0.19.0
0.18.3
0.18.2
0.18.1
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.0
0.13.0
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.12.3
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.5
0.10.4
0.10.3
0.10.2
0.10.1
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.5
0.8.4
0.8.3
0.8.1
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.0
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.0
0.2.0
Labels
Clear labels
bug
Something is not working

Archived

enhancement
New feature

Archived

Contribution welcome
Get started contributing here
Good first issue
Good if you are new to the project or to open source contributions
Impact
External
Affects the people using the project
Impact
Internal
Affects on the people working on the project
Priority
Critical
Work on right now
Priority
High
Work on at earliest convenience
Priority
Low
Work on in spare time
Priority
Medium
Work on regularly
Review
Duplicate
Already exists
Review
Off Topic
Does not fall within the scope of the repo/project
Status
Backlog
Is not being worked on yet
Status
Blocked
Is waiting on something or someone
Status
Completed
Is done
Status
In Progress
Is being worked on
Status
Investigating
Is waiting on research or questions
Status
Needs Decision
Is waiting on a decision by the devs/contributors
Status
Needs Info
Is waiting on additional information before it can be solved
Status
Needs Triage
Is new issue that needs reviewing
Status
Testing
Is being checked and verified
Status
Waiting For Review
Is waiting on reviewers to approve
Status
Won't Fix
Won't be fixed
Type
Bug
Related to something not working as intended
Type
CI
Related to continuous integration
Type
Documentation
Related to documentation
Type
Enhancement
Related to a new feature or an improved one
Type
New Claim
Related to a new identity claim/proof
Type
Security
Related to security
Type
Tests
Related to code tests
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
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
keyoxide/doipjs#98
Reference in a new issue
keyoxide/doipjs
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?