updated plugin ActivityPub version 9.1.0
This commit is contained in:
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user