Skip to content

Commit 7bdf7d7

Browse files
committed
fix: better filtering and capability check for get data Codeinwp/visualizer-pro#433
1 parent bd329f7 commit 7bdf7d7

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

classes/Visualizer/Module/Chart.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function __construct( Visualizer_Plugin $plugin ) {
5959
$this->_addAjaxAction( Visualizer_Plugin::ACTION_CLONE_CHART, 'cloneChart' );
6060
$this->_addAjaxAction( Visualizer_Plugin::ACTION_EXPORT_DATA, 'exportData' );
6161

62+
error_log( var_export( 'REGISTER ACTION', true ) );
6263
$this->_addAjaxAction( Visualizer_Plugin::ACTION_FETCH_DB_DATA, 'getQueryData' );
6364
$this->_addAjaxAction( Visualizer_Plugin::ACTION_SAVE_DB_QUERY, 'saveQuery' );
6465

@@ -1421,6 +1422,10 @@ private function _handleDataPage() {
14211422
public function getQueryData() {
14221423
check_ajax_referer( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION, 'security' );
14231424

1425+
if ( ! current_user_can( 'edit_posts' ) ) {
1426+
wp_send_json_error( array( 'msg' => __( 'Action not allowed for this user.', 'visualizer' ) ) );
1427+
}
1428+
14241429
$params = wp_parse_args( $_POST['params'] );
14251430
$chart_id = filter_var( $params['chart_id'], FILTER_VALIDATE_INT );
14261431

classes/Visualizer/Source/Query.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public function fetch( $as_html = false, $results_as_numeric_array = false, $raw
8080
}
8181

8282
// only select queries allowed.
83-
if ( preg_match( '/^\s*(insert|delete|update|replace|create|alter|drop|truncate)\s/i', $this->_query ) ) {
83+
if ( preg_match( '/\s*(insert|delete|update|replace|create|alter|drop|truncate)\s/i', $this->_query ) ) {
8484
$this->_error = __( 'Only SELECT queries are allowed', 'visualizer' );
8585
return false;
8686
}

tests/test-ajax.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
/**
3+
* WordPress unit test plugin.
4+
*
5+
* @package visualizer
6+
* @subpackage Tests
7+
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8+
* @since 3.10.12
9+
*/
10+
11+
class Test_Visualizer_Ajax extends WP_Ajax_UnitTestCase {
12+
13+
private $admin_user_id;
14+
15+
public function setUp() :void {
16+
parent::setUp();
17+
$this->admin_user_id = $this->factory->user->create(
18+
array(
19+
'role' => 'administrator',
20+
)
21+
);
22+
wp_set_current_user( $this->admin_user_id );
23+
24+
}
25+
26+
public function test_ajax_response_get_query_data_valid_query() {
27+
$this->_setRole( 'administrator' );
28+
29+
$_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION );
30+
31+
$_POST['params'] = array(
32+
'query' => 'SELECT * FROM wp_posts',
33+
);
34+
try {
35+
// Trigger the AJAX action
36+
$this->_handleAjax( Visualizer_Plugin::ACTION_FETCH_DB_DATA );
37+
} catch (WPAjaxDieContinueException $e) {
38+
// We expected this, do nothing.
39+
}
40+
41+
$response = json_decode( $this->_last_response );
42+
$this->assertIsObject( $response );
43+
$this->assertObjectHasAttribute( 'success', $response );
44+
$this->assertObjectHasAttribute( 'data', $response );
45+
$this->assertTrue( $response->success );
46+
}
47+
48+
public function test_ajax_response_get_query_data_invalid_query() {
49+
$this->_setRole( 'administrator' );
50+
51+
$_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION );
52+
53+
$_POST['params'] = array(
54+
'query' => "/**/UPDATE wp_options SET option_value='administrator' WHERE option_name='default_role' --",
55+
);
56+
try {
57+
// Trigger the AJAX action
58+
$this->_handleAjax( Visualizer_Plugin::ACTION_FETCH_DB_DATA );
59+
} catch (WPAjaxDieContinueException $e) {
60+
// We expected this, do nothing.
61+
}
62+
63+
$response = json_decode( $this->_last_response );
64+
$this->assertIsObject( $response );
65+
$this->assertObjectHasAttribute( 'success', $response );
66+
$this->assertObjectHasAttribute( 'data', $response );
67+
$this->assertEquals( 'Only SELECT queries are allowed', $response->data->msg );
68+
$this->assertFalse( $response->success );
69+
}
70+
71+
public function test_ajax_response_get_query_data_subcriber_dissallow() {
72+
$this->_setRole( 'subscriber' );
73+
74+
$_GET['security'] = wp_create_nonce( Visualizer_Plugin::ACTION_FETCH_DB_DATA . Visualizer_Plugin::VERSION );
75+
76+
$_POST['params'] = array(
77+
'query' => "/**/UPDATE wp_options SET option_value='administrator' WHERE option_name='default_role' --",
78+
);
79+
try {
80+
// Trigger the AJAX action
81+
$this->_handleAjax( Visualizer_Plugin::ACTION_FETCH_DB_DATA );
82+
} catch (WPAjaxDieContinueException $e) {
83+
// We expected this, do nothing.
84+
}
85+
86+
$response = json_decode( $this->_last_response );
87+
$this->assertIsObject( $response );
88+
$this->assertObjectHasAttribute( 'success', $response );
89+
$this->assertObjectHasAttribute( 'data', $response );
90+
$this->assertEquals( 'Action not allowed for this user.', $response->data->msg );
91+
$this->assertFalse( $response->success );
92+
}
93+
}

0 commit comments

Comments
 (0)