From 76b523e2a7d9e65d3ac308703396592034bb11a5 Mon Sep 17 00:00:00 2001 From: Faisal Ahammad Date: Wed, 15 Jul 2026 16:44:23 +0600 Subject: [PATCH] fix: resolve Plugin Check input-handling warnings Unslash and sanitize superglobal reads flagged by WordPress.org Plugin Check in our own code. Vendored dependencies/ and dev-only tests/ were left untouched. - Simple_Document_Library::get_table() now wp_unslash()'s the DataTables AJAX POST params and validates the order array (scalar column index range-checked against the column list, sort direction restricted to asc/desc). - Settings::sanitize_shortcode_settings() guards, unslashes and sanitize_key()'s the option_page request var. - Document_Link::save() unslashes the nonce before wp_verify_nonce(). Skipped: ~56 warnings in phpScoper-scoped vendor libraries, test scaffolding, the core the_content hook, and the intentional taxonomy tax_query. The readme.txt mismatched_plugin_name item is intentionally excluded from this build. --- src/Admin/Metabox/Document_Link.php | 2 +- src/Admin/Settings.php | 4 +++- src/Simple_Document_Library.php | 21 ++++++++++++++++----- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Admin/Metabox/Document_Link.php b/src/Admin/Metabox/Document_Link.php index 83f1d82..d79dc2c 100644 --- a/src/Admin/Metabox/Document_Link.php +++ b/src/Admin/Metabox/Document_Link.php @@ -117,7 +117,7 @@ public function render( $post ) { */ public function save( $post_id ) { // Verify nonce - if ( ! isset( $_POST['dll_document_link_nonce'] ) || ! wp_verify_nonce( $_POST['dll_document_link_nonce'], 'dll_save_document_link' ) ) { + if ( ! isset( $_POST['dll_document_link_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['dll_document_link_nonce'] ), 'dll_save_document_link' ) ) { return; } diff --git a/src/Admin/Settings.php b/src/Admin/Settings.php index e010d74..ca79f62 100644 --- a/src/Admin/Settings.php +++ b/src/Admin/Settings.php @@ -185,7 +185,9 @@ public function sanitize_document_page( $page_setting ) { */ public function sanitize_shortcode_settings( $args ) { $existing_options = $this->get_existing_shortcode_options(); - $option_page = $_REQUEST['option_page']; + $option_page = isset( $_REQUEST['option_page'] ) + ? sanitize_key( wp_unslash( $_REQUEST['option_page'] ) ) + : ''; if ( ! $option_page ) { return array_merge( $existing_options, $args ); diff --git a/src/Simple_Document_Library.php b/src/Simple_Document_Library.php index 9a23570..a4cafcc 100644 --- a/src/Simple_Document_Library.php +++ b/src/Simple_Document_Library.php @@ -54,11 +54,22 @@ public function get_table( $output_type = 'html' ) { $columns = $this->get_columns(); // Parse DataTables parameters from the AJAX request - $draw = isset( $_POST['draw'] ) ? intval( $_POST['draw'] ) : 1; - $this->args['offset'] = isset( $_POST['start'] ) ? intval( $_POST['start'] ) : 0; - $this->args['rows_per_page'] = isset( $_POST['length'] ) && intval( $_POST['length'] ) !== -1 ? intval( $_POST['length'] ) : $this->args['rows_per_page']; - $this->args['sort_by'] = isset( $_POST['order'] ) ? $columns[$_POST['order'][0]['column']] : $this->get_orderby(); - $this->args['sort_order'] = isset( $_POST['order'] ) ? sanitize_key( $_POST['order'][0]['dir'] ) : $this->args['sort_order']; + $draw = isset( $_POST['draw'] ) ? intval( wp_unslash( $_POST['draw'] ) ) : 1; + $this->args['offset'] = isset( $_POST['start'] ) ? intval( wp_unslash( $_POST['start'] ) ) : 0; + $this->args['rows_per_page'] = isset( $_POST['length'] ) && intval( wp_unslash( $_POST['length'] ) ) !== -1 ? intval( wp_unslash( $_POST['length'] ) ) : $this->args['rows_per_page']; + $order = isset( $_POST['order'] ) && is_array( $_POST['order'] ) ? wp_unslash( $_POST['order'] ) : []; + $column_index = isset( $order[0]['column'] ) && is_scalar( $order[0]['column'] ) + ? filter_var( $order[0]['column'], FILTER_VALIDATE_INT ) + : false; + $this->args['sort_by'] = false !== $column_index && $column_index >= 0 && isset( $columns[ $column_index ] ) + ? $columns[ $column_index ] + : $this->get_orderby(); + $direction = isset( $order[0]['dir'] ) && is_scalar( $order[0]['dir'] ) + ? sanitize_key( (string) $order[0]['dir'] ) + : ''; + if ( in_array( $direction, [ 'asc', 'desc' ], true ) ) { + $this->args['sort_order'] = $direction; + } $this->args['search_value'] = isset( $_POST['search']['value'] ) ? sanitize_text_field( wp_unslash( $_POST['search']['value'] ) ) : ''; $this->args['rows_per_page'] = filter_var( $this->args['rows_per_page'], FILTER_VALIDATE_INT );