WordPress.org

Make WordPress Core

#44096 closed defect (bug) (fixed)

REST API: Taxonomy and term endpoints should use correct permission checks

Reported by: danielbachhuber Owned by: pento
Milestone: 4.9.8 Priority: normal
Severity: normal Version:
Component: Taxonomy Keywords: has-patch has-unit-tests commit fixed-major
Focuses: rest-api Cc:
PR Number:

Description

There are a couple of key changes we need to make:

  1. Switch GET /wp/v2/taxonomies?context=edit to reference $taxonomy->cap->assign_terms instead of $taxonomy->cap->manage_terms. Users who can assign terms need to be able to see all corresponding labeling.
  2. Permit users with $taxonomy->cap->assign_terms to create terms for non-hierarchical taxonomies (e.g. tags).

These suggestions are based on research for WordPress/gutenberg#5879, which I'll copy below for posterity.


Here's my table of UI-focused permission review.

The key difference between categories and tags: contributors and authors can create tags, but they can't create categories. This distinction applies more broadly to non-hierarchical vs. hierarchical taxonomies.

Fortunately, the only low-level permissions check is in wp_insert_post(). More specifically:

foreach ( $postarr['tax_input'] as $taxonomy => $tags ) {
	$taxonomy_obj = get_taxonomy( $taxonomy );
	// array = hierarchical, string = non-hierarchical.
	if ( is_array( $tags ) ) {
		$tags = array_filter( $tags );
	}
	if ( current_user_can( $taxonomy_obj->cap->assign_terms ) ) {
		wp_set_post_terms( $post_ID, $tags, $taxonomy );
	}
}

After this logic, wp_set_post_terms() calls wp_set_object_terms() and neither has permissions checks. Because of how wp_set_object_terms() behaves, strings passed for a non-hierarchical taxonomy will be magically transformed into terms. wp_set_object_terms() always expects an array of integers (representing valid terms) for hierarchical taxonomies.

I say "fortunately" because core's existing implementation also means we don't have to enter the rabbit hole of developer-defined custom taxonomy UI. edit_post() blindly accepts and processes data included in tax_input, regardless of whether a developer implemented some bespoke UI for the taxonomy.

Given this information, we can assume:

  1. A user can set terms on a post if they have assign_terms for the taxonomy and can edit the post. This also means they can access all terms (including empty, non-public ones).
  2. A user can create new terms if they have assign_terms for a non-hierarchical taxonomy, or edit_terms for a hierarchical taxonomy.

However, now we run into WordPress/gutenberg#6361 because capabilities are evaluated at runtime.

Attachments (1)

44096.1.diff (7.9 KB) - added by danielbachhuber 19 months ago.

Download all attachments as: .zip

Change History (10)

#1 @desrosj
19 months ago

  • Milestone changed from 4.9.7 to 4.9.8

Moving all tickets in 4.9.7 to 4.9.8.

#2 @danielbachhuber
18 months ago

  • Milestone changed from 4.9.8 to 4.9.7

#3 @danielbachhuber
17 months ago

  • Keywords commit added
  • Owner set to pento
  • Status changed from new to assigned

#4 @danielbachhuber
17 months ago

  • Milestone changed from 4.9.7 to 4.9.8

#5 @pento
17 months ago

  • Keywords needs-refresh added; commit removed

After applying 44096.1.diff to trunk, I get two failing unit tests:

1) WP_Test_REST_Tags_Controller::test_create_item_contributor
Failed asserting that 403 matches expected 201.

/wordpress-develop/tests/phpunit/tests/rest-api/rest-tags-controller.php:640

2) WP_Test_REST_Taxonomies_Controller::test_get_items_context_edit
Failed asserting that 3 matches expected 2.

/wordpress-develop/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php:72

@danielbachhuber, can you get them fixed up, please?

#6 @danielbachhuber
17 months ago

@pento Did you run grunt build?

#7 @pento
17 months ago

  • Resolution set to fixed
  • Status changed from assigned to closed

In 43440:

REST API: Tweak permission checks for taxonomy and term endpoints

To match behaviour in the Classic Editor, we need to slightly loosen permissions on taxonomy and term endpoints. This allows users to create terms to assign to a post that they're editing.

Props danielbachhuber.
Fixes #44096.

#8 @pento
17 months ago

  • Keywords commit fixed-major added; needs-refresh removed
  • Resolution fixed deleted
  • Status changed from closed to reopened

#9 @pento
17 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 43443:

REST API: Tweak permission checks for taxonomy and term endpoints

To match behaviour in the Classic Editor, we need to slightly loosen permissions on taxonomy and term endpoints. This allows users to create terms to assign to a post that they're editing.

Merges [43440] to the 4.9 branch.

Props danielbachhuber.
Fixes #44096.

Note: See TracTickets for help on using tickets.