Skip to content

Only accept activities signed with the actor's own key - #3979

Merged
pfefferle merged 5 commits into
trunkfrom
fix/signing-key-owner
Oct 28, 2026
Merged

pfefferle merged 5 commits into
trunkfrom
fix/signing-key-owner

Conversation

@pfefferle

Copy link
Copy Markdown
Member

Fixes #

Proposed changes:

  • An incoming activity is now only accepted when the key that signed it belongs to the activity's actor. Before, any key from the same host was enough, so on a server where users hold their own keys, one account's key passed for another account on that server.
  • Remote_Actors::get_public_key() reports the actor the key was taken from (the stored actor, or the one fetched from the key's host), and both verifiers return that owner instead of the keyId. verify_key_id() compares it with the actor and still fails closed on identifiers without a host.
  • Signature::verify_http_signature() and Http_Signature::verify() now return the id of the actor that owns the verified key instead of the keyId. In the plugin only the inbox verification uses the value, the router only checks for an error. I did not find other callers.
  • The docblock of get_remote_metadata_by_actor() explains why Proxy::get() should be used instead.

Other information:

  • Have you written new tests for your changes, if applicable?

This follows what Mastodon does: it looks up the stored key with its account first, fetches only on a miss, and rejects an activity whose actor is not the key's account (different_actor?). I checked Mastodon's FeatureRequest and QuoteRequest: both are signed with the requesting account's own #main-key, so they still pass.

Same-host activities signed with another actor's key (for example a server or instance actor) are now rejected, as Mastodon does. Same-host key aliases keep working, because the owner is compared, not the keyId string.

I could not test this live: my local site cannot be reached from outside, so tags.pub and mastodon.social reject its signed fetches. I checked the documents by hand: tags.pub serves a standalone CryptographicKey with owner set to the actor, and a Mastodon #main-key resolves to the actor document. Both give the actor as owner.

Testing instructions:

  • Run vendor/bin/phpunit --filter 'test_verify_key_id|test_get_public_key_sets_owner|test_get_public_key_rejects_a_key_id_without_host|redirected_signing_key'.
  • On a public test site, follow a Mastodon account and a tags.pub hashtag, then check that their Creates and Updates still arrive.

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch
  • Minor
  • Major

Type

  • Added - for new features
  • Changed - for changes in existing functionality
  • Deprecated - for soon-to-be removed features
  • Removed - for now removed features
  • Fixed - for any bug fixes
  • Security - in case of vulnerabilities

Message

@pfefferle
pfefferle merged commit 596e81b into trunk Oct 28, 2026
12 checks passed
@pfefferle
pfefferle deleted the fix/signing-key-owner branch October 28, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant