updated plugin ActivityPub version 9.1.0

This commit is contained in:
2026-07-28 15:03:10 +00:00
committed by Gitium
parent bf428f0e45
commit ff806e1811
217 changed files with 6098 additions and 3025 deletions

View File

@ -11,6 +11,8 @@ use Activitypub\Emoji;
use Activitypub\Sanitize;
use function Activitypub\generate_post_summary;
use function Activitypub\is_same_actor;
use function Activitypub\is_same_host;
use function Activitypub\object_to_uri;
use function Activitypub\process_remote_media;
@ -70,6 +72,30 @@ class Remote_Posts {
return self::update( $activity, $recipients );
}
// An actor may only create posts attributed to itself; only the actor is signature-bound, not attributedTo.
if ( ! is_same_actor( $activity['actor'] ?? '', $activity_object['attributedTo'] ?? '' ) ) {
return new \WP_Error(
'activitypub_create_unauthorized',
\__( 'The Create actor does not match the object attributedTo.', 'activitypub' ),
array( 'status' => 403 )
);
}
/*
* A post is cached under its own id (guid), so that id must live on the same host
* as its author. Otherwise a signed Create could cache a post under a different
* host's object id, mis-recording its origin and taking over that id, so the
* genuine post can no longer overwrite the cached copy (the update owner-check
* would then reject the real author).
*/
if ( ! is_same_host( $activity_object['id'] ?? '', $activity['actor'] ?? '' ) ) {
return new \WP_Error(
'activitypub_create_host_mismatch',
\__( 'The object id must be on the same host as the actor.', 'activitypub' ),
array( 'status' => 403 )
);
}
// Post doesn't exist, create new post.
$actor = Remote_Actors::fetch_by_uri( object_to_uri( $activity_object['attributedTo'] ) );
@ -152,6 +178,25 @@ class Remote_Posts {
return $post;
}
/*
* Only the post's author may update it. When the activity carries an actor (every
* signature-verified inbound activity does), compare it against the remote actor
* stored when the post was first cached (its guid is the actor URI), so a remote
* server cannot overwrite another host's cached post by sending an Update whose
* object.id points at a post it does not own. The actor must be used here, not the
* payload's attributedTo, because only the actor is bound to the HTTP signature.
*/
if ( isset( $activity['actor'] ) ) {
$owner = \get_post( (int) \get_post_meta( $post->ID, '_activitypub_remote_actor_id', true ) );
if ( ! $owner instanceof \WP_Post || object_to_uri( $activity['actor'] ) !== $owner->guid ) {
return new \WP_Error(
'activitypub_update_forbidden',
\__( 'Update failed: the actor does not own this post.', 'activitypub' ),
array( 'status' => 403 )
);
}
}
$post_array = self::activity_to_post( $activity['object'] );
$post_array['ID'] = $post->ID;
$post_id = \wp_update_post( $post_array, true );
@ -512,7 +557,7 @@ class Remote_Posts {
\wp_delete_post( $post_id, true );
}
return count( $post_ids );
return \count( $post_ids );
}
/**