PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.7.1
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.7.1
2.7.1 2.7.2 2.7.0 2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 All 141 releases
← All changes | admin/class-metasync-otto-debug.php +34 -20 2.6.24 → 2.7.1 View file →
@@ -49,12 +49,26 @@
49 49 }
50 50
51 51
52 52 /**
53 - * Add debug menu (developer only - hidden by default)
53 + * Whether debug tooling is allowed to run at all right now.
54 + *
55 + * `manage_options` alone isn't a real restriction — every site admin has
56 + * it, so this page and its AJAX handlers were reachable by anyone on any
57 + * site. Hard-disabled: the menu item, the page, and every AJAX handler
58 + * are unreachable for all users on all sites, no toggle or capability
59 + * bypasses this. The class and its methods are left in place; only
60 + * access is blocked.
54 61 */
62 + private static function is_debug_tools_enabled() {
63 + return false;
64 + }
65 +
66 + /**
67 + * Add debug menu (internal only - hidden on customer production sites)
68 + */
55 69 public function add_debug_menu() {
56 - if (!current_user_can('manage_options')) {
70 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
57 71 return;
58 72 }
59 73
60 74 $menu_slug = Metasync_Admin::$page_slug;
@@ -72,9 +86,9 @@
72 86 /**
73 87 * Create the debug page
74 88 */
75 89 public function create_debug_page() {
76 - if (!current_user_can('manage_options')) {
90 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
77 91 wp_die('Unauthorized');
78 92 }
79 93
80 94 $whitelabel_otto_name = Metasync::get_whitelabel_otto_name();
@@ -643,9 +657,9 @@
643 657 */
644 658 private function get_option_last_updated($option_name) {
645 659 global $wpdb;
646 660
647 - $result = $wpdb->get_var($wpdb->prepare(
661 + $result = $wpdb->get_var($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- admin debug tool — scratch diagnostics storage outside any WordPress API
648 662 "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s",
649 663 $option_name
650 664 ));
651 665
@@ -651,9 +665,9 @@
651 665
652 666 if ($result) {
653 667 $data = maybe_unserialize($result);
654 668 if (isset($data['last_updated'])) {
655 - return date('Y-m-d H:i:s', $data['last_updated']);
669 + return gmdate('Y-m-d H:i:s', $data['last_updated']);
656 670 }
657 671 }
658 672
659 673 return 'Unknown';
@@ -760,9 +774,9 @@
760 774 */
761 775 public function ajax_test_otto_api() {
762 776 check_ajax_referer('metasync_otto_debug', 'nonce');
763 777
764 - if (!current_user_can('manage_options')) {
778 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
765 779 wp_die('Unauthorized');
766 780 }
767 781
768 782 $general_options = Metasync::get_option('general');
@@ -816,9 +830,9 @@
816 830 */
817 831 public function ajax_test_notification_endpoint() {
818 832 check_ajax_referer('metasync_otto_debug', 'nonce');
819 833
820 - if (!current_user_can('manage_options')) {
834 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
821 835 wp_die('Unauthorized');
822 836 }
823 837
824 838 $endpoint_url = rest_url('metasync/v1/otto_crawl_notify');
@@ -859,9 +873,9 @@
859 873 */
860 874 public function ajax_clear_otto_cache() {
861 875 check_ajax_referer('metasync_otto_debug', 'nonce');
862 876
863 - if (!current_user_can('manage_options')) {
877 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
864 878 wp_die('Unauthorized');
865 879 }
866 880
867 881 // Clear crawl data
@@ -891,9 +905,9 @@
891 905 */
892 906 public function ajax_simulate_crawl_notification() {
893 907 check_ajax_referer('metasync_otto_debug', 'nonce');
894 908
895 - if (!current_user_can('manage_options')) {
909 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
896 910 wp_die('Unauthorized');
897 911 }
898 912
899 913 $general_options = Metasync::get_option('general');
@@ -930,9 +944,9 @@
930 944 public function ajax_test_specific_url() {
931 945 try {
932 946 check_ajax_referer('metasync_otto_debug', 'nonce');
933 947
934 - if (!current_user_can('manage_options')) {
948 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
935 949 wp_die('Unauthorized');
936 950 }
937 951
938 952 $test_url = sanitize_url($_POST['test_url'] ?? '');
@@ -964,9 +978,9 @@
964 978
965 979 wp_send_json_success($results);
966 980
967 981 } catch (Exception $e) {
968 - error_log('MetaSync OTTO Debug: Exception in ajax_test_specific_url: ' . $e->getMessage());
982 + error_log('MetaSync OTTO Debug: Exception in ajax_test_specific_url: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- unreachable in production
969 983 wp_send_json_error('Exception: ' . $e->getMessage());
970 984 }
971 985 }
972 986
@@ -975,9 +989,9 @@
975 989 */
976 990 public function ajax_emulate_otto_changes() {
977 991 check_ajax_referer('metasync_otto_debug', 'nonce');
978 992
979 - if (!current_user_can('manage_options')) {
993 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
980 994 wp_die('Unauthorized');
981 995 }
982 996
983 997 $test_url = sanitize_url($_POST['test_url'] ?? '');
@@ -1097,9 +1111,9 @@
1097 1111 /**
1098 1112 * Test page type detection
1099 1113 */
1100 1114 private function test_page_type_detection($url) {
1101 - $parsed_url = parse_url($url);
1115 + $parsed_url = wp_parse_url($url);
1102 1116 $path = $parsed_url['path'] ?? '/';
1103 1117
1104 1118 $detection = array(
1105 1119 'url' => $url,
@@ -1198,9 +1212,9 @@
1198 1212 public function ajax_simple_test() {
1199 1213 try {
1200 1214 check_ajax_referer('metasync_otto_debug', 'nonce');
1201 1215
1202 - if (!current_user_can('manage_options')) {
1216 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
1203 1217 wp_send_json_error('Unauthorized');
1204 1218 }
1205 1219
1206 1220 wp_send_json_success(array(
@@ -1210,9 +1224,9 @@
1210 1224 'nonce_verified' => true
1211 1225 ));
1212 1226
1213 1227 } catch (Exception $e) {
1214 - error_log('MetaSync OTTO Debug: Exception in ajax_simple_test: ' . $e->getMessage());
1228 + error_log('MetaSync OTTO Debug: Exception in ajax_simple_test: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- unreachable in production
1215 1229 wp_send_json_error('Exception: ' . $e->getMessage());
1216 1230 }
1217 1231 }
1218 1232
@@ -1222,9 +1236,9 @@
1222 1236 public function ajax_test_db_permissions() {
1223 1237 try {
1224 1238 check_ajax_referer('metasync_otto_debug', 'nonce');
1225 1239
1226 - if (!current_user_can('manage_options')) {
1240 + if (!current_user_can('manage_options') || !self::is_debug_tools_enabled()) {
1227 1241 wp_send_json_error('Unauthorized');
1228 1242 }
1229 1243
1230 1244 $results = array(
@@ -1244,9 +1258,9 @@
1244 1258
1245 1259 // Test 2: Check if we can access Action Scheduler tables
1246 1260 global $wpdb;
1247 1261 $table_name = $wpdb->prefix . 'actionscheduler_actions';
1248 - $table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name'") == $table_name;
1262 + $table_exists = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($table_name))) == $table_name; // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- admin debug tool — scratch diagnostics storage outside any WordPress API
1249 1263
1250 1264 $results['tests']['table_access'] = array(
1251 1265 'table_exists' => $table_exists,
1252 1266 'table_name' => $table_name,
@@ -1254,9 +1268,9 @@
1254 1268 );
1255 1269
1256 1270 // Test 3: Try to insert a test record
1257 1271 if ($table_exists) {
1258 - $insert_result = $wpdb->insert(
1272 + $insert_result = $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- admin debug tool — scratch diagnostics storage outside any WordPress API
1259 1273 $table_name,
1260 1274 array(
1261 1275 'hook' => 'metasync_debug_test',
1262 1276 'status' => 'pending',
@@ -1275,9 +1289,9 @@
1275 1289 );
1276 1290
1277 1291 // Clean up test record
1278 1292 if ($insert_result !== false && $wpdb->insert_id) {
1279 - $wpdb->delete($table_name, array('ID' => $wpdb->insert_id));
1293 + $wpdb->delete($table_name, array('ID' => $wpdb->insert_id)); // phpcs:ignore WordPress.DB.DirectDatabaseQuery -- admin debug tool — scratch diagnostics storage outside any WordPress API
1280 1294 }
1281 1295 }
1282 1296
1283 1297 // Test 4: Check WordPress cron functionality
@@ -1289,9 +1303,9 @@
1289 1303
1290 1304 wp_send_json_success($results);
1291 1305
1292 1306 } catch (Exception $e) {
1293 - error_log('MetaSync OTTO Debug: Exception in ajax_test_db_permissions: ' . $e->getMessage());
1307 + error_log('MetaSync OTTO Debug: Exception in ajax_test_db_permissions: ' . $e->getMessage()); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- unreachable in production
1294 1308 wp_send_json_error('Exception: ' . $e->getMessage());
1295 1309 }
1296 1310 }
1297 1311 }