Changeset 3369213
- Timestamp:
- 09/28/2025 02:03:22 PM (6 months ago)
- Location:
- maintenance-switch
- Files:
-
- 10 added
- 12 edited
- 1 copied
-
tags/1.6.4 (copied) (copied from maintenance-switch/trunk)
-
tags/1.6.4/.editorconfig (added)
-
tags/1.6.4/.vscode (added)
-
tags/1.6.4/.vscode/settings.json (added)
-
tags/1.6.4/.vscode/wordpress-stubs.php (added)
-
tags/1.6.4/admin/class-maintenance-switch-admin.php (modified) (2 diffs)
-
tags/1.6.4/admin/js/maintenance-switch-admin.js (modified) (2 diffs)
-
tags/1.6.4/includes/class-maintenance-switch.php (modified) (4 diffs)
-
tags/1.6.4/maintenance-switch.php (modified) (1 diff)
-
tags/1.6.4/phpcs.xml (added)
-
tags/1.6.4/preview.php (modified) (3 diffs)
-
tags/1.6.4/readme.txt (modified) (1 diff)
-
trunk/.editorconfig (added)
-
trunk/.vscode (added)
-
trunk/.vscode/settings.json (added)
-
trunk/.vscode/wordpress-stubs.php (added)
-
trunk/admin/class-maintenance-switch-admin.php (modified) (2 diffs)
-
trunk/admin/js/maintenance-switch-admin.js (modified) (2 diffs)
-
trunk/includes/class-maintenance-switch.php (modified) (4 diffs)
-
trunk/maintenance-switch.php (modified) (1 diff)
-
trunk/phpcs.xml (added)
-
trunk/preview.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
maintenance-switch/tags/1.6.4/admin/class-maintenance-switch-admin.php
r3369156 r3369213 114 114 wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/maintenance-switch-admin.js', array('jquery'), $this->version, false); 115 115 wp_enqueue_code_editor(['file' => $this->plugin_name . '.php']); 116 117 // Add variables for tab persistence 118 // Check both GET and POST for active_tab (GET survives WordPress redirect) 119 $active_tab = 0; 120 if (isset($_GET['active_tab'])) { 121 $active_tab = intval(sanitize_text_field($_GET['active_tab'])); 122 } elseif (isset($_POST['active_tab'])) { 123 $active_tab = intval(sanitize_text_field($_POST['active_tab'])); 124 } 125 126 // Better detection for WordPress options form submission 127 $was_submitted = ( 128 isset($_GET['settings-updated']) || // After redirect from options.php 129 isset($_POST['submit']) || 130 isset($_POST['option_page']) || 131 (isset($_POST['action']) && $_POST['action'] === 'update') 132 ); 133 134 wp_localize_script($this->plugin_name, 'maintenance_switch_admin', array( 135 'active_tab' => $active_tab, 136 'submitted' => $was_submitted ? 1 : 0 137 )); 116 138 } 117 139 wp_enqueue_script($this->plugin_name . '-button', plugin_dir_url(dirname(__FILE__)) . 'assets/js/maintenance-switch-button.js', array('jquery'), time(), false); … … 177 199 178 200 /** 201 * Preserve active tab parameter in WordPress redirect 202 * 203 * @since 1.6.3 204 */ 205 public function preserve_active_tab_in_redirect($location, $status) 206 { 207 // Only apply to our settings page redirects 208 if (strpos($location, 'options-general.php') !== false && 209 strpos($location, 'page=maintenance-switch') !== false && 210 isset($_POST['active_tab'])) { 211 212 $active_tab = intval(sanitize_text_field($_POST['active_tab'])); 213 214 // Add active_tab parameter to the redirect URL 215 $separator = strpos($location, '?') !== false ? '&' : '?'; 216 $location = $location . $separator . 'active_tab=' . $active_tab; 217 } 218 219 return $location; 220 } 221 222 /** 179 223 * Check if the current screen is the settings page 180 224 * -
maintenance-switch/tags/1.6.4/admin/js/maintenance-switch-admin.js
r3369156 r3369213 9 9 }); 10 10 11 $("#settings-tabs").tabs(); 11 // Initialize tabs with active tab persistence 12 var tabs = $("#settings-tabs").tabs(); 13 14 // Get active tab from various sources (priority order) 15 var activeTabIndex = 0; 16 var urlHash = window.location.hash; 17 var phpActiveTab = typeof maintenance_switch_admin !== 'undefined' ? maintenance_switch_admin.active_tab : null; 18 var wasSubmitted = typeof maintenance_switch_admin !== 'undefined' ? maintenance_switch_admin.submitted : 0; 19 var savedTab = localStorage.getItem('ms_active_tab'); 20 21 // Priority: PHP post data > URL hash > localStorage > default 22 if (wasSubmitted && phpActiveTab !== null) { 23 activeTabIndex = parseInt(phpActiveTab) || 0; 24 } else if (urlHash) { 25 // Find tab index by hash 26 $("#settings-tabs ul li a").each(function(index) { 27 if ($(this).attr('href') === urlHash) { 28 activeTabIndex = index; 29 return false; 30 } 31 }); 32 } else if (savedTab !== null) { 33 activeTabIndex = parseInt(savedTab) || 0; 34 } 35 36 // Activate the correct tab 37 tabs.tabs("option", "active", activeTabIndex); 38 39 // Save active tab on change 40 tabs.on("tabsactivate", function(event, ui) { 41 var activeIndex = ui.newTab.index(); 42 localStorage.setItem('ms_active_tab', activeIndex); 43 // Update URL hash without triggering page refresh 44 var tabId = ui.newPanel.attr('id'); 45 history.replaceState(null, null, '#' + tabId); 46 }); 47 48 // Intercept form submissions to maintain active tab 49 $('form#settings-form').on('submit', function() { 50 var activeTab = tabs.tabs("option", "active"); 51 localStorage.setItem('ms_active_tab', activeTab); 52 53 // Remove existing active_tab input to avoid duplicates 54 $(this).find('input[name="active_tab"]').remove(); 55 56 // Add tab parameter as hidden input (will be caught by redirect hook) 57 var tabInput = $('<input>').attr({ 58 type: 'hidden', 59 name: 'active_tab', 60 value: activeTab 61 }); 62 $(this).append(tabInput); 63 }); 12 64 13 65 $("#addmyip").on("click", function (e) { … … 47 99 } else { 48 100 var html = $("#ms_page_html").val(); 49 form50 .attr("action", form.data("default-action"))51 .html(52 $("<input/>").attr({53 type: "hidden",54 id: "preview-code",55 name: "preview-code",56 value: html,57 })58 )59 .submit();101 // Clear only the preview-code input if it exists, preserve nonce 102 form.find("input[name='preview-code']").remove(); 103 form.append( 104 $("<input/>").attr({ 105 type: "hidden", 106 id: "preview-code", 107 name: "preview-code", 108 value: html, 109 }) 110 ); 111 form.attr("action", form.data("default-action")).submit(); 60 112 } 61 113 }); -
maintenance-switch/tags/1.6.4/includes/class-maintenance-switch.php
r3369189 r3369213 213 213 $plugin_basename = plugin_basename(plugin_dir_path(__DIR__) . $this->plugin_name . '.php'); 214 214 $this->loader->add_filter('plugin_action_links_' . $plugin_basename, $plugin_admin, 'add_action_links'); 215 216 // Add hook to preserve active tab in WordPress redirect 217 $this->loader->add_filter('wp_redirect', $plugin_admin, 'preserve_active_tab_in_redirect', 10, 2); 215 218 216 219 // Add an action for the switch button … … 880 883 881 884 $allowed_ips = $this->get_setting('ms_allowed_ips'); 882 $allowed_ips = explode(',', $allowed_ips);885 $allowed_ips = explode(',', (string)$allowed_ips); 883 886 return $allowed_ips; 884 887 } … … 1016 1019 // apply flags replacements 1017 1020 $content = str_replace('{{MS_PLUGIN_SLUG}}', $this->plugin_name, $content); 1018 $content = str_replace('{{MS_USE_THEME_FILE}}', $use_theme_file, $content);1019 $content = str_replace('{{MS_RETURN_503}}', $return503, $content);1021 $content = str_replace('{{MS_USE_THEME_FILE}}', (string)$use_theme_file, $content); 1022 $content = str_replace('{{MS_RETURN_503}}', (string)$return503, $content); 1020 1023 $content = str_replace('{{MS_THEME_FILE}}', $theme_file, $content); 1021 1024 $content = str_replace('{{MS_PAGE_HTML}}', $page_html, $content); … … 1044 1047 // get flags values 1045 1048 $allowed_users = "'" . implode("', '", $this->get_allowed_users()) . "'"; 1046 $allowed_ips = "'" . implode("','", $this->get_allowed_ips()) . "'"; 1049 $allowed_ips_array = $this->get_allowed_ips(); 1050 $allowed_ips = "'" . implode("','", is_array($allowed_ips_array) ? $allowed_ips_array : array()) . "'"; 1047 1051 $login_url = str_replace(get_site_url(), '', wp_login_url()); 1048 1052 -
maintenance-switch/tags/1.6.4/maintenance-switch.php
r3369189 r3369213 17 17 * Plugin URI: https://wordpress.org/plugins/maintenance-switch 18 18 * Description: Customize easily and switch in one-click to (native) maintenance mode from your backend or frontend. 19 * Version: 1.6. 319 * Version: 1.6.4 20 20 * Author: Fugu 21 21 * Author URI: http://www.fugu.fr -
maintenance-switch/tags/1.6.4/preview.php
r3369189 r3369213 1 1 <?php 2 2 3 // If this file is called directly, abort.3 // Load WordPress if not already loaded 4 4 if (!defined('WPINC')) { 5 die; 5 // Try to find and load WordPress 6 $wp_load_paths = [ 7 '../../../wp-load.php', // Standard plugin path 8 '../../../../wp-load.php', // In case of subdirectories 9 '../../../../../wp-load.php' // Deep subdirectories 10 ]; 11 12 $wp_loaded = false; 13 foreach ($wp_load_paths as $path) { 14 if (file_exists($path)) { 15 require_once($path); 16 $wp_loaded = true; 17 break; 18 } 19 } 20 21 // If WordPress couldn't be loaded, we can't do security checks 22 if (!$wp_loaded) { 23 // Fallback for direct access - basic security 24 if (!isset($_POST['preview-code'])) { 25 die('Direct access not allowed'); 26 } 27 } 6 28 } 7 29 8 // Security check: only allow admin users 9 if (!current_user_can('manage_options')) { 10 wp_die(__('Insufficient permissions to access this page.')); 11 } 30 // Security checks (only if WordPress is loaded) 31 if (defined('WPINC')) { 32 // Security check: only allow admin users 33 if (function_exists('current_user_can') && !current_user_can('manage_options')) { 34 wp_die(__('Insufficient permissions to access this page.')); 35 } 12 36 13 // Security check: verify nonce 14 if (!empty($_POST['preview-code'])) { 15 if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'maintenance_switch_preview')) { 16 wp_die(__('Security check failed.')); 37 // Security check: verify nonce 38 if (!empty($_POST['preview-code'])) { 39 if (function_exists('wp_verify_nonce') && (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'maintenance_switch_preview'))) { 40 wp_die(__('Security check failed.')); 41 } 17 42 } 18 43 } … … 28 53 29 54 // Displaying this page during the maintenance mode 30 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? sanitize_text_field($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 55 if (function_exists('sanitize_text_field')) { 56 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? sanitize_text_field($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 57 } else { 58 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? strip_tags($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 59 } 60 31 61 if ('HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol) 32 62 $protocol = 'HTTP/1.0'; … … 34 64 35 65 if (!empty($_POST['preview-code'])) { 36 echo wp_kses_post(wp_unslash(sanitize_textarea_field($_POST['preview-code']))); 66 if (function_exists('wp_kses_post')) { 67 echo wp_kses_post(wp_unslash(sanitize_textarea_field($_POST['preview-code']))); 68 } else { 69 // Fallback: output HTML directly for preview (admin-only context) 70 // Clean the input but preserve HTML structure 71 $html = stripslashes($_POST['preview-code']); 72 73 // Basic security: remove dangerous tags and attributes 74 $dangerous_tags = ['script', 'iframe', 'object', 'embed', 'form', 'input', 'textarea']; 75 foreach ($dangerous_tags as $tag) { 76 $html = preg_replace('/<\s*' . $tag . '[^>]*>.*?<\s*\/\s*' . $tag . '\s*>/is', '', $html); 77 $html = preg_replace('/<\s*' . $tag . '[^>]*\/?>/is', '', $html); 78 } 79 80 // Remove dangerous attributes 81 $html = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $html); 82 $html = preg_replace('/javascript\s*:/i', '', $html); 83 84 echo $html; 85 } 37 86 } -
maintenance-switch/tags/1.6.4/readme.txt
r3369189 r3369213 5 5 Requires at least: 3.5 6 6 Tested up to: 6.3 7 Stable tag: 1.6. 37 Stable tag: 1.6.4 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later -
maintenance-switch/trunk/admin/class-maintenance-switch-admin.php
r3369156 r3369213 114 114 wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/maintenance-switch-admin.js', array('jquery'), $this->version, false); 115 115 wp_enqueue_code_editor(['file' => $this->plugin_name . '.php']); 116 117 // Add variables for tab persistence 118 // Check both GET and POST for active_tab (GET survives WordPress redirect) 119 $active_tab = 0; 120 if (isset($_GET['active_tab'])) { 121 $active_tab = intval(sanitize_text_field($_GET['active_tab'])); 122 } elseif (isset($_POST['active_tab'])) { 123 $active_tab = intval(sanitize_text_field($_POST['active_tab'])); 124 } 125 126 // Better detection for WordPress options form submission 127 $was_submitted = ( 128 isset($_GET['settings-updated']) || // After redirect from options.php 129 isset($_POST['submit']) || 130 isset($_POST['option_page']) || 131 (isset($_POST['action']) && $_POST['action'] === 'update') 132 ); 133 134 wp_localize_script($this->plugin_name, 'maintenance_switch_admin', array( 135 'active_tab' => $active_tab, 136 'submitted' => $was_submitted ? 1 : 0 137 )); 116 138 } 117 139 wp_enqueue_script($this->plugin_name . '-button', plugin_dir_url(dirname(__FILE__)) . 'assets/js/maintenance-switch-button.js', array('jquery'), time(), false); … … 177 199 178 200 /** 201 * Preserve active tab parameter in WordPress redirect 202 * 203 * @since 1.6.3 204 */ 205 public function preserve_active_tab_in_redirect($location, $status) 206 { 207 // Only apply to our settings page redirects 208 if (strpos($location, 'options-general.php') !== false && 209 strpos($location, 'page=maintenance-switch') !== false && 210 isset($_POST['active_tab'])) { 211 212 $active_tab = intval(sanitize_text_field($_POST['active_tab'])); 213 214 // Add active_tab parameter to the redirect URL 215 $separator = strpos($location, '?') !== false ? '&' : '?'; 216 $location = $location . $separator . 'active_tab=' . $active_tab; 217 } 218 219 return $location; 220 } 221 222 /** 179 223 * Check if the current screen is the settings page 180 224 * -
maintenance-switch/trunk/admin/js/maintenance-switch-admin.js
r3369156 r3369213 9 9 }); 10 10 11 $("#settings-tabs").tabs(); 11 // Initialize tabs with active tab persistence 12 var tabs = $("#settings-tabs").tabs(); 13 14 // Get active tab from various sources (priority order) 15 var activeTabIndex = 0; 16 var urlHash = window.location.hash; 17 var phpActiveTab = typeof maintenance_switch_admin !== 'undefined' ? maintenance_switch_admin.active_tab : null; 18 var wasSubmitted = typeof maintenance_switch_admin !== 'undefined' ? maintenance_switch_admin.submitted : 0; 19 var savedTab = localStorage.getItem('ms_active_tab'); 20 21 // Priority: PHP post data > URL hash > localStorage > default 22 if (wasSubmitted && phpActiveTab !== null) { 23 activeTabIndex = parseInt(phpActiveTab) || 0; 24 } else if (urlHash) { 25 // Find tab index by hash 26 $("#settings-tabs ul li a").each(function(index) { 27 if ($(this).attr('href') === urlHash) { 28 activeTabIndex = index; 29 return false; 30 } 31 }); 32 } else if (savedTab !== null) { 33 activeTabIndex = parseInt(savedTab) || 0; 34 } 35 36 // Activate the correct tab 37 tabs.tabs("option", "active", activeTabIndex); 38 39 // Save active tab on change 40 tabs.on("tabsactivate", function(event, ui) { 41 var activeIndex = ui.newTab.index(); 42 localStorage.setItem('ms_active_tab', activeIndex); 43 // Update URL hash without triggering page refresh 44 var tabId = ui.newPanel.attr('id'); 45 history.replaceState(null, null, '#' + tabId); 46 }); 47 48 // Intercept form submissions to maintain active tab 49 $('form#settings-form').on('submit', function() { 50 var activeTab = tabs.tabs("option", "active"); 51 localStorage.setItem('ms_active_tab', activeTab); 52 53 // Remove existing active_tab input to avoid duplicates 54 $(this).find('input[name="active_tab"]').remove(); 55 56 // Add tab parameter as hidden input (will be caught by redirect hook) 57 var tabInput = $('<input>').attr({ 58 type: 'hidden', 59 name: 'active_tab', 60 value: activeTab 61 }); 62 $(this).append(tabInput); 63 }); 12 64 13 65 $("#addmyip").on("click", function (e) { … … 47 99 } else { 48 100 var html = $("#ms_page_html").val(); 49 form50 .attr("action", form.data("default-action"))51 .html(52 $("<input/>").attr({53 type: "hidden",54 id: "preview-code",55 name: "preview-code",56 value: html,57 })58 )59 .submit();101 // Clear only the preview-code input if it exists, preserve nonce 102 form.find("input[name='preview-code']").remove(); 103 form.append( 104 $("<input/>").attr({ 105 type: "hidden", 106 id: "preview-code", 107 name: "preview-code", 108 value: html, 109 }) 110 ); 111 form.attr("action", form.data("default-action")).submit(); 60 112 } 61 113 }); -
maintenance-switch/trunk/includes/class-maintenance-switch.php
r3369189 r3369213 213 213 $plugin_basename = plugin_basename(plugin_dir_path(__DIR__) . $this->plugin_name . '.php'); 214 214 $this->loader->add_filter('plugin_action_links_' . $plugin_basename, $plugin_admin, 'add_action_links'); 215 216 // Add hook to preserve active tab in WordPress redirect 217 $this->loader->add_filter('wp_redirect', $plugin_admin, 'preserve_active_tab_in_redirect', 10, 2); 215 218 216 219 // Add an action for the switch button … … 880 883 881 884 $allowed_ips = $this->get_setting('ms_allowed_ips'); 882 $allowed_ips = explode(',', $allowed_ips);885 $allowed_ips = explode(',', (string)$allowed_ips); 883 886 return $allowed_ips; 884 887 } … … 1016 1019 // apply flags replacements 1017 1020 $content = str_replace('{{MS_PLUGIN_SLUG}}', $this->plugin_name, $content); 1018 $content = str_replace('{{MS_USE_THEME_FILE}}', $use_theme_file, $content);1019 $content = str_replace('{{MS_RETURN_503}}', $return503, $content);1021 $content = str_replace('{{MS_USE_THEME_FILE}}', (string)$use_theme_file, $content); 1022 $content = str_replace('{{MS_RETURN_503}}', (string)$return503, $content); 1020 1023 $content = str_replace('{{MS_THEME_FILE}}', $theme_file, $content); 1021 1024 $content = str_replace('{{MS_PAGE_HTML}}', $page_html, $content); … … 1044 1047 // get flags values 1045 1048 $allowed_users = "'" . implode("', '", $this->get_allowed_users()) . "'"; 1046 $allowed_ips = "'" . implode("','", $this->get_allowed_ips()) . "'"; 1049 $allowed_ips_array = $this->get_allowed_ips(); 1050 $allowed_ips = "'" . implode("','", is_array($allowed_ips_array) ? $allowed_ips_array : array()) . "'"; 1047 1051 $login_url = str_replace(get_site_url(), '', wp_login_url()); 1048 1052 -
maintenance-switch/trunk/maintenance-switch.php
r3369189 r3369213 17 17 * Plugin URI: https://wordpress.org/plugins/maintenance-switch 18 18 * Description: Customize easily and switch in one-click to (native) maintenance mode from your backend or frontend. 19 * Version: 1.6. 319 * Version: 1.6.4 20 20 * Author: Fugu 21 21 * Author URI: http://www.fugu.fr -
maintenance-switch/trunk/preview.php
r3369189 r3369213 1 1 <?php 2 2 3 // If this file is called directly, abort.3 // Load WordPress if not already loaded 4 4 if (!defined('WPINC')) { 5 die; 5 // Try to find and load WordPress 6 $wp_load_paths = [ 7 '../../../wp-load.php', // Standard plugin path 8 '../../../../wp-load.php', // In case of subdirectories 9 '../../../../../wp-load.php' // Deep subdirectories 10 ]; 11 12 $wp_loaded = false; 13 foreach ($wp_load_paths as $path) { 14 if (file_exists($path)) { 15 require_once($path); 16 $wp_loaded = true; 17 break; 18 } 19 } 20 21 // If WordPress couldn't be loaded, we can't do security checks 22 if (!$wp_loaded) { 23 // Fallback for direct access - basic security 24 if (!isset($_POST['preview-code'])) { 25 die('Direct access not allowed'); 26 } 27 } 6 28 } 7 29 8 // Security check: only allow admin users 9 if (!current_user_can('manage_options')) { 10 wp_die(__('Insufficient permissions to access this page.')); 11 } 30 // Security checks (only if WordPress is loaded) 31 if (defined('WPINC')) { 32 // Security check: only allow admin users 33 if (function_exists('current_user_can') && !current_user_can('manage_options')) { 34 wp_die(__('Insufficient permissions to access this page.')); 35 } 12 36 13 // Security check: verify nonce 14 if (!empty($_POST['preview-code'])) { 15 if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'maintenance_switch_preview')) { 16 wp_die(__('Security check failed.')); 37 // Security check: verify nonce 38 if (!empty($_POST['preview-code'])) { 39 if (function_exists('wp_verify_nonce') && (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field($_POST['_wpnonce']), 'maintenance_switch_preview'))) { 40 wp_die(__('Security check failed.')); 41 } 17 42 } 18 43 } … … 28 53 29 54 // Displaying this page during the maintenance mode 30 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? sanitize_text_field($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 55 if (function_exists('sanitize_text_field')) { 56 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? sanitize_text_field($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 57 } else { 58 $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? strip_tags($_SERVER['SERVER_PROTOCOL']) : 'HTTP/1.0'; 59 } 60 31 61 if ('HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol) 32 62 $protocol = 'HTTP/1.0'; … … 34 64 35 65 if (!empty($_POST['preview-code'])) { 36 echo wp_kses_post(wp_unslash(sanitize_textarea_field($_POST['preview-code']))); 66 if (function_exists('wp_kses_post')) { 67 echo wp_kses_post(wp_unslash(sanitize_textarea_field($_POST['preview-code']))); 68 } else { 69 // Fallback: output HTML directly for preview (admin-only context) 70 // Clean the input but preserve HTML structure 71 $html = stripslashes($_POST['preview-code']); 72 73 // Basic security: remove dangerous tags and attributes 74 $dangerous_tags = ['script', 'iframe', 'object', 'embed', 'form', 'input', 'textarea']; 75 foreach ($dangerous_tags as $tag) { 76 $html = preg_replace('/<\s*' . $tag . '[^>]*>.*?<\s*\/\s*' . $tag . '\s*>/is', '', $html); 77 $html = preg_replace('/<\s*' . $tag . '[^>]*\/?>/is', '', $html); 78 } 79 80 // Remove dangerous attributes 81 $html = preg_replace('/\s*on\w+\s*=\s*["\'][^"\']*["\']/i', '', $html); 82 $html = preg_replace('/javascript\s*:/i', '', $html); 83 84 echo $html; 85 } 37 86 } -
maintenance-switch/trunk/readme.txt
r3369189 r3369213 5 5 Requires at least: 3.5 6 6 Tested up to: 6.3 7 Stable tag: 1.6. 37 Stable tag: 1.6.4 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later
Note: See TracChangeset
for help on using the changeset viewer.