0

I recently noticed a new feature in the Gutenberg editor (I'm guessing introduced in Wordpress 5.8) that seemingly allows any user to post as any other user:

enter image description here

I confirmed that using this new option, a user belonging to the Author role was able to successfully to post as a user belonging to the Admin role. Why on Earth was this feature introduced with seemingly no permissions checks, and can it be disabled?

5
  • Not all roles can do this, are you testing this as an administrator/editor? The WP editor has always allowed this, even in the classic editor going back a decade ( perhaps the author metabox was turrned off in the top drawer at the time )
    – Tom J Nowell
    Aug 31 at 15:00
  • @TomJNowell As stated in the post I was testing as an Author. My Author role has one or two additional caps added, but nothing that would logically allow a user to post as someone else let alone an Administrator, but then the documentation around caps is so sparse that it's hard to know for sure. The entire concept of posting as another user seems so niche and open to abuse that it feels like it should be limited to admins, but at the very least it should be a separate cap that can be explicitly disabled. Aug 31 at 16:09
  • which caps did you add? Caps sometimes have side effects, they're not always as precise as their names suggest. Have you tried this as a contributor? Authors posting things under other peoples names is not as unusual as you might think, lots of people post things on behalf of someone else and author attribution can change for many reasons. As for it being a separate capability, you should suggest that on WP Trac. The furthest i've been able to track this down is WP 2.0 lcom.static.linuxfound.org/var/slashimages/… this predates the classic editor
    – Tom J Nowell
    Aug 31 at 16:22
  • Also what kind of abuse are you talking about? Users who were given access to assign authors that then assign authors doesn't make much sense as a failure mode. As far as I can see, edit_posts is the capability in question, it doesn't get more granular, e.g. there is no edit_title etc, any granularity comes in the form of editing a particular post type, etc
    – Tom J Nowell
    Aug 31 at 16:30
  • @HashimAziz You must have added some incorrect capability. I just tested with a fresh install of WordPress 5.8 and an author cannot assign another author to their posts. The "Author" option is not visible in the UI.
    – Phil
    Aug 31 at 16:52
1

This has been present since before the block editor, and even the classic editor, and can be seen in WordPress 2.0. It even predates proper metaboxes!

In the block editor, the presence of the author field depends on wether the user has the action wp:action-assign-author, but there is no direct capability that determines this.

If we take a look at the authorship plugin we see that it can be removed:

/**
 * Filters the post data for a REST API response.
 *
 * This removes the `wp:action-assign-author` rel from the response so the default post author
 * control doesn't get shown on the block editor post editing screen.
 *
 * This also adds a new `authorship:action-assign-authorship` rel so custom clients can refer to this.
 *
 * @param WP_REST_Response $response The response object.
 * @param WP_Post          $post     Post object.
 * @param WP_REST_Request  $request  Request object.
 * @return WP_REST_Response The response object.
 */
function rest_prepare_post( WP_REST_Response $response, WP_Post $post, WP_REST_Request $request ) : WP_REST_Response {
    $links = $response->get_links();

    if ( isset( $links['https://api.w.org/action-assign-author'] ) ) {
        $response->remove_link( 'https://api.w.org/action-assign-author' );
        $response->add_link( REST_REL_LINK_ID, $links['self'][0]['href'] );
    }

    return $response;
}

So something like this might remove it for all users when editing posts:

/**
 * Filters the post data for a REST API response.
 *
 * This removes the `wp:action-assign-author` rel from the response so the default post author
 * control doesn't get shown on the block editor post editing screen.
 *
 * @param WP_REST_Response $response The response object.
 * @param WP_Post          $post     Post object.
 * @param WP_REST_Request  $request  Request object.
 * @return WP_REST_Response The response object.
 */
function rest_prepare_post_remove_author_action( WP_REST_Response $response, WP_Post $post, WP_REST_Request $request ) : WP_REST_Response {
    $links = $response->get_links();

    if ( isset( $links['https://api.w.org/action-assign-author'] ) ) {
        $response->remove_link( 'https://api.w.org/action-assign-author' );
    }

    return $response;
}
add_filter( 'rest_prepare_post', 'rest_prepare_post_remove_author_action', 10, 3 );

You may then adjust it to contain a role/capability check. Note that this may be purely cosmetic, users who directly make requests to the API, or use the classic editor, can still set the author.

This just fools the block editor and other well behaving REST API applications into believing it isn't possible.

1
  • Upvoted and accepted for being the most complete solution that allows for the best of both worlds rather than navigating the mess that is Wordpress' caps. Aug 31 at 21:32
1

After a lot of testing (easier since I remembered that any cap added to a role with add_cap has to explicitly be removed with remove_cap rather than just removing the add_cap call, and that even wp-cli can't help for this purpose), I finally managed to determine that...


This dropdown is a side effect of the edit_others_posts capability

I had originally enabled this cap for my Author role because another of its side effects is the ability to moderate (i.e. Approve, Spam or Bin) comments, even when the moderate_comments capability is also enabled. Enabling edit_others_posts at the time was the only way to allow my Author role to moderate comments, just as disabling it now is the only way to prevent my Author role from posting as another user.

In other words, Wordpress' cap system is so messy and interdependent that if I want to prevent a role from pretending to post as another user, I can't also allow that role to moderate comments - two completely different functions that should be unrelated.

I even understand why they're related - because a post needs to be editable for its comments to be - but these caps should really be separated out, because editing a post and moderating spam on it are two different logical domains, and therefore two different roles. This is clearly understood on some level because the moderate_comments cap exists, but clearly it would have been too intuitive for Wordpress to make it the only cap that lets users... moderate comments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.