From 2bcb43ef7296b679943eead2e0ab35d6204bb2e0 Mon Sep 17 00:00:00 2001 From: lucadobrescu <252785083+lucadobrescu@users.noreply.github.com> Date: Mon, 27 Jul 2026 12:21:49 +0300 Subject: [PATCH] fix: check per-post edit_post capability in chart_data REST field The chart_data REST field callback only checked the generic edit_posts capability, so any contributor could read the full backend configuration of any chart (data source query, settings, JSON endpoint auth headers) via GET /wp-json/wp/v2/visualizer/{id}. Check edit_post on the requested chart instead, so access follows the standard post capability map (author or edit_others_posts). Fixes Codeinwp/visualizer-pro#605 Co-Authored-By: Claude Fable 5 --- classes/Visualizer/Gutenberg/Block.php | 2 +- tests/test-chart-data-permissions.php | 60 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tests/test-chart-data-permissions.php diff --git a/classes/Visualizer/Gutenberg/Block.php b/classes/Visualizer/Gutenberg/Block.php index 1111c86b..93a0cb58 100644 --- a/classes/Visualizer/Gutenberg/Block.php +++ b/classes/Visualizer/Gutenberg/Block.php @@ -276,7 +276,7 @@ public function register_rest_endpoints() { * Get Post Meta Fields */ public function get_visualizer_data( $post ) { - if ( ! current_user_can( 'edit_posts' ) ) { + if ( ! current_user_can( 'edit_post', $post['id'] ) ) { return false; } diff --git a/tests/test-chart-data-permissions.php b/tests/test-chart-data-permissions.php new file mode 100644 index 00000000..aa2391bb --- /dev/null +++ b/tests/test-chart-data-permissions.php @@ -0,0 +1,60 @@ +post->create( + array( + 'post_type' => Visualizer_Plugin::CPT_VISUALIZER, + 'post_author' => $author_id, + 'post_content' => wp_slash( serialize( array( array( 'Label' ), array( 'Value' ) ) ) ), + ) + ); + update_post_meta( $chart_id, Visualizer_Plugin::CF_CHART_TYPE, 'line' ); + update_post_meta( $chart_id, Visualizer_Plugin::CF_SETTINGS, array() ); + update_post_meta( $chart_id, Visualizer_Plugin::CF_SERIES, array( array( 'label' => 'Label', 'type' => 'string' ) ) ); + return $chart_id; + } + + /** + * A contributor must not read another user's chart configuration. + */ + public function test_contributor_cannot_read_others_chart_data() { + $author_id = self::factory()->user->create( array( 'role' => 'editor' ) ); + $chart_id = $this->create_chart( $author_id ); + + wp_set_current_user( self::factory()->user->create( array( 'role' => 'contributor' ) ) ); + + $result = Visualizer_Gutenberg_Block::get_instance()->get_visualizer_data( array( 'id' => $chart_id ) ); + $this->assertFalse( $result ); + } + + /** + * The chart author can still read their own chart configuration. + */ + public function test_author_can_read_own_chart_data() { + $author_id = self::factory()->user->create( array( 'role' => 'editor' ) ); + $chart_id = $this->create_chart( $author_id ); + + wp_set_current_user( $author_id ); + + $result = Visualizer_Gutenberg_Block::get_instance()->get_visualizer_data( array( 'id' => $chart_id ) ); + $this->assertIsArray( $result ); + } +}