diff --git a/classes/Visualizer/Module.php b/classes/Visualizer/Module.php
index 13d7cbfc1..ae7993917 100644
--- a/classes/Visualizer/Module.php
+++ b/classes/Visualizer/Module.php
@@ -650,7 +650,7 @@ protected function get_inline_custom_css( $id, $settings ) {
$class_name = $id . $name;
$properties = implode( ' !important; ', array_filter( $attributes ) );
if ( ! empty( $properties ) ) {
- $css .= '.' . $class_name . ' {' . $properties . ' !important;}';
+ $css .= wp_strip_all_tags( '.' . $class_name . ' {' . $properties . ' !important;}' );
$classes[ $name ] = $class_name;
}
}
diff --git a/classes/Visualizer/Module/Wizard.php b/classes/Visualizer/Module/Wizard.php
index 3a1007521..c3256e61d 100644
--- a/classes/Visualizer/Module/Wizard.php
+++ b/classes/Visualizer/Module/Wizard.php
@@ -153,6 +153,12 @@ public function visualizer_enqueue_setup_wizard_scripts() {
* @return bool|void
*/
public function dismissWizard( $redirect_to_dashboard = true ) {
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( esc_html__( 'You do not have permission to perform this action.', 'visualizer' ), '', array( 'response' => 403 ) );
+ }
+ if ( false !== $redirect_to_dashboard ) {
+ check_admin_referer( 'visualizer_dismiss_wizard' );
+ }
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$status = isset( $_REQUEST['status'] ) ? (int) $_REQUEST['status'] : 0;
update_option( 'visualizer_fresh_install', $status );
@@ -169,6 +175,9 @@ public function dismissWizard( $redirect_to_dashboard = true ) {
*/
public function visualizer_wizard_step_process() {
check_ajax_referer( VISUALIZER_ABSPATH, 'security' );
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_send_json( array( 'status' => 0 ), 403 );
+ }
$step = ! empty( $_POST['step'] ) ? sanitize_text_field( wp_unslash( $_POST['step'] ) ) : 1;
switch ( $step ) {
case 'step_2':
diff --git a/templates/setup-wizard.php b/templates/setup-wizard.php
index e78178027..eccd04163 100644
--- a/templates/setup-wizard.php
+++ b/templates/setup-wizard.php
@@ -6,12 +6,15 @@
* @package Templates
*/
-$dashboard_url = add_query_arg(
- array(
- 'action' => 'visualizer_dismiss_wizard',
- 'status' => 0,
+$dashboard_url = wp_nonce_url(
+ add_query_arg(
+ array(
+ 'action' => 'visualizer_dismiss_wizard',
+ 'status' => 0,
+ ),
+ admin_url( 'admin.php' )
),
- admin_url( 'admin.php' )
+ 'visualizer_dismiss_wizard'
);
$chart_id = ! empty( $this->wizard_data['chart_id'] ) ? (int) $this->wizard_data['chart_id'] : '';
diff --git a/tests/e2e/config/mu-plugins/plant-chart-settings.php b/tests/e2e/config/mu-plugins/plant-chart-settings.php
new file mode 100644
index 000000000..5222e9de8
--- /dev/null
+++ b/tests/e2e/config/mu-plugins/plant-chart-settings.php
@@ -0,0 +1,42 @@
+\d+)',
+ array(
+ 'methods' => 'POST',
+ 'permission_callback' => function () {
+ return current_user_can( 'manage_options' );
+ },
+ 'callback' => function ( WP_REST_Request $request ) {
+ $chart_id = (int) $request['id'];
+ $body = $request->get_json_params();
+ if ( isset( $body['settings'] ) ) {
+ update_post_meta( $chart_id, 'visualizer-settings', $body['settings'] );
+ }
+ if ( isset( $body['series'] ) ) {
+ update_post_meta( $chart_id, 'visualizer-series', $body['series'] );
+ }
+ if ( isset( $body['content'] ) ) {
+ wp_update_post(
+ array(
+ 'ID' => $chart_id,
+ 'post_content' => maybe_serialize( $body['content'] ),
+ )
+ );
+ }
+ return array( 'ok' => true );
+ },
+ )
+ );
+ }
+);
diff --git a/tests/e2e/specs/custom-css.spec.js b/tests/e2e/specs/custom-css.spec.js
new file mode 100644
index 000000000..1b2fb22f5
--- /dev/null
+++ b/tests/e2e/specs/custom-css.spec.js
@@ -0,0 +1,51 @@
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+let chartId;
+
+test.describe( 'Custom CSS sanitization', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ const chart = await requestUtils.rest( {
+ method: 'POST',
+ path: '/wp/v2/visualizer',
+ data: { title: 'Custom CSS payload chart', status: 'publish' },
+ } );
+ chartId = chart.id;
+
+ await requestUtils.rest( {
+ method: 'POST',
+ path: `/visualizer-e2e/v1/chart-settings/${ chartId }`,
+ data: {
+ settings: {
+ customcss: {
+ title: {
+ color: 'red