/** * Check whether a user has the permissions to see a page from the plugin. * * @return void */ public static function check_permissions() { if (!function_exists('current_user_can') || !current_user_can('manage_options')) { $page = SucuriScanRequest::get('page', '_page'); $page = SucuriScan::escape($page); wp_die(__('Access denied by <b>Sucuri</b> to see <code>' . $page . '</code>')); } }
/** * Generate the HTML code necessary to render a list of options in a form. * * @param array $allowed_values List with keys and values allowed for the options. * @param string $selected_val Value of the option that will be selected by default. * @return string Option list for a select form field. */ public static function get_select_options($allowed_values = array(), $selected_val = '') { $options = ''; foreach ($allowed_values as $option_name => $option_label) { $selected_str = ''; if ($option_name == $selected_val) { $selected_str = 'selected="selected"'; } $options .= sprintf("<option value=\"%s\" %s>%s</option>\n", SucuriScan::escape($option_name), SucuriScan::escape($selected_str), SucuriScan::escape($option_label)); } return $options; }
/** * Send a notifications to the administrator of some specific events that are * not triggered through an hooked action, but through a simple request in the * admin interface. * * @return integer Either one or zero representing the success or fail of the operation. */ public static function hook_undefined_actions() { $plugin_activate_actions = '(activate|deactivate)(\\-selected)?'; $plugin_update_actions = '(upgrade-plugin|do-plugin-upgrade|update-selected)'; // Plugin activation and/or deactivation. if (current_user_can('activate_plugins') && (SucuriScanRequest::get_or_post('action', $plugin_activate_actions) || SucuriScanRequest::get_or_post('action2', $plugin_activate_actions))) { $plugin_list = array(); $items_affected = array(); // Get the action performed through action or action2 params. $action_d = SucuriScanRequest::get_or_post('action'); if ($action_d == '-1') { $action_d = SucuriScanRequest::get_or_post('action2'); } $action_d .= 'd'; if (SucuriScanRequest::get('plugin', '.+') && strpos($_SERVER['REQUEST_URI'], 'plugins.php') !== false) { $plugin_list[] = SucuriScanRequest::get('plugin'); } elseif (isset($_POST['checked']) && is_array($_POST['checked']) && !empty($_POST['checked'])) { $plugin_list = SucuriScanRequest::post('checked', '_array'); $action_d = str_replace('-selected', '', $action_d); } foreach ($plugin_list as $plugin) { $plugin_info = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin); if (!empty($plugin_info['Name']) && !empty($plugin_info['Version'])) { $items_affected[] = sprintf('%s (v%s; %s)', self::escape($plugin_info['Name']), self::escape($plugin_info['Version']), self::escape($plugin)); } } // Report activated/deactivated plugins at once. if (!empty($items_affected)) { $message_tpl = count($items_affected) > 1 ? 'Plugins %s: (multiple entries): %s' : 'Plugin %s: %s'; $message = sprintf($message_tpl, $action_d, @implode(',', $items_affected)); self::report_warning_event($message); self::notify_event('plugin_' . $action_d, $message); } } elseif (current_user_can('update_plugins') && (SucuriScanRequest::get_or_post('action', $plugin_update_actions) || SucuriScanRequest::get_or_post('action2', $plugin_update_actions))) { $plugin_list = array(); $items_affected = array(); if (SucuriScanRequest::get('plugin', '.+') && strpos($_SERVER['REQUEST_URI'], 'wp-admin/update.php') !== false) { $plugin_list[] = SucuriScanRequest::get('plugin', '.+'); } elseif (isset($_POST['checked']) && is_array($_POST['checked']) && !empty($_POST['checked'])) { $plugin_list = SucuriScanRequest::post('checked', '_array'); } foreach ($plugin_list as $plugin) { $plugin_info = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin); if (!empty($plugin_info['Name']) && !empty($plugin_info['Version'])) { $items_affected[] = sprintf('%s (v%s; %s)', self::escape($plugin_info['Name']), self::escape($plugin_info['Version']), self::escape($plugin)); } } // Report updated plugins at once. if (!empty($items_affected)) { $message_tpl = count($items_affected) > 1 ? 'Plugins updated: (multiple entries): %s' : 'Plugin updated: %s'; $message = sprintf($message_tpl, @implode(',', $items_affected)); self::report_warning_event($message); self::notify_event('plugin_updated', $message); } } elseif (current_user_can('install_plugins') && SucuriScanRequest::get('action', '(install|upload)-plugin')) { if (isset($_FILES['pluginzip'])) { $plugin = self::escape($_FILES['pluginzip']['name']); } else { $plugin = SucuriScanRequest::get('plugin', '.+'); if (!$plugin) { $plugin = 'Unknown'; } } $message = 'Plugin installed: ' . self::escape($plugin); SucuriScanEvent::report_warning_event($message); self::notify_event('plugin_installed', $message); } elseif (current_user_can('delete_plugins') && SucuriScanRequest::post('action', 'delete-selected') && SucuriScanRequest::post('verify-delete', '1')) { $plugin_list = SucuriScanRequest::post('checked', '_array'); $items_affected = array(); foreach ((array) $plugin_list as $plugin) { $plugin_info = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin); if (!empty($plugin_info['Name']) && !empty($plugin_info['Version'])) { $items_affected[] = sprintf('%s (v%s; %s)', self::escape($plugin_info['Name']), self::escape($plugin_info['Version']), self::escape($plugin)); } } // Report deleted plugins at once. if (!empty($items_affected)) { $message_tpl = count($items_affected) > 1 ? 'Plugins deleted: (multiple entries): %s' : 'Plugin deleted: %s'; $message = sprintf($message_tpl, @implode(',', $items_affected)); self::report_warning_event($message); self::notify_event('plugin_deleted', $message); } } elseif (current_user_can('edit_plugins') && SucuriScanRequest::post('action', 'update') && SucuriScanRequest::post('plugin', '.+') && SucuriScanRequest::post('file', '.+') && strpos($_SERVER['REQUEST_URI'], 'plugin-editor.php') !== false) { $filename = SucuriScanRequest::post('file'); $message = 'Plugin editor used in: ' . SucuriScan::escape($filename); self::report_error_event($message); self::notify_event('theme_editor', $message); } elseif (current_user_can('edit_themes') && SucuriScanRequest::post('action', 'update') && SucuriScanRequest::post('theme', '.+') && SucuriScanRequest::post('file', '.+') && strpos($_SERVER['REQUEST_URI'], 'theme-editor.php') !== false) { $theme_name = SucuriScanRequest::post('theme'); $filename = SucuriScanRequest::post('file'); $message = 'Theme editor used in: ' . SucuriScan::escape($theme_name) . '/' . SucuriScan::escape($filename); self::report_error_event($message); self::notify_event('theme_editor', $message); } elseif (current_user_can('install_themes') && SucuriScanRequest::get('action', 'install-theme')) { $theme = SucuriScanRequest::get('theme', '.+'); if (!$theme) { $theme = 'Unknown'; } $message = 'Theme installed: ' . self::escape($theme); SucuriScanEvent::report_warning_event($message); self::notify_event('theme_installed', $message); } elseif (current_user_can('delete_themes') && SucuriScanRequest::get_or_post('action', 'delete') && SucuriScanRequest::get_or_post('stylesheet', '.+')) { $theme = SucuriScanRequest::get('stylesheet', '.+'); if (!$theme) { $theme = 'Unknown'; } $message = 'Theme deleted: ' . self::escape($theme); SucuriScanEvent::report_warning_event($message); self::notify_event('theme_deleted', $message); } elseif (current_user_can('update_themes') && SucuriScanRequest::get('action', '(upgrade-theme|do-theme-upgrade)') && SucuriScanRequest::post('checked', '_array')) { $themes = SucuriScanRequest::post('checked', '_array'); $items_affected = array(); foreach ((array) $themes as $theme) { $theme_info = wp_get_theme($theme); $theme_name = ucwords($theme); $theme_version = '0.0'; if ($theme_info->exists()) { $theme_name = $theme_info->get('Name'); $theme_version = $theme_info->get('Version'); } $items_affected[] = sprintf('%s (v%s; %s)', self::escape($theme_name), self::escape($theme_version), self::escape($theme)); } // Report updated themes at once. if (!empty($items_affected)) { $message_tpl = count($items_affected) > 1 ? 'Themes updated: (multiple entries): %s' : 'Theme updated: %s'; $message = sprintf($message_tpl, @implode(',', $items_affected)); self::report_warning_event($message); self::notify_event('theme_updated', $message); } } elseif (current_user_can('update_core') && SucuriScanRequest::get('action', '(do-core-upgrade|do-core-reinstall)') && SucuriScanRequest::post('upgrade')) { $message = 'WordPress updated to version: ' . SucuriScanRequest::post('version'); self::report_critical_event($message); self::notify_event('website_updated', $message); } elseif (current_user_can('edit_theme_options') && SucuriScanRequest::post('action', 'save-widget') && SucuriScanRequest::post('id_base') !== false && SucuriScanRequest::post('sidebar') !== false) { if (SucuriScanRequest::post('delete_widget', '1')) { $action_d = 'deleted'; $action_text = 'deleted from'; } else { $action_d = 'added'; $action_text = 'added to'; } $message = sprintf('Widget %s (%s) %s %s (#%d; size %dx%d)', SucuriScanRequest::post('id_base'), SucuriScanRequest::post('widget-id'), $action_text, SucuriScanRequest::post('sidebar'), SucuriScanRequest::post('widget_number'), SucuriScanRequest::post('widget-width'), SucuriScanRequest::post('widget-height')); self::report_warning_event($message); self::notify_event('widget_' . $action_d, $message); } elseif (current_user_can('manage_options') && SucuriScanOption::check_options_nonce()) { // Get the settings available in the database and compare them with the submission. $options_changed = SucuriScanOption::what_options_were_changed($_POST); $options_changed_str = ''; $options_changed_simple = ''; $options_changed_count = 0; // Generate the list of options changed. foreach ($options_changed['original'] as $option_name => $option_value) { $options_changed_count += 1; $options_changed_str .= sprintf("The value of the option <b>%s</b> was changed from <b>'%s'</b> to <b>'%s'</b>.<br>\n", self::escape($option_name), self::escape($option_value), self::escape($options_changed['changed'][$option_name])); $options_changed_simple .= sprintf("%s: from '%s' to '%s',", self::escape($option_name), self::escape($option_value), self::escape($options_changed['changed'][$option_name])); } // Get the option group (name of the page where the request was originated). $option_page = isset($_POST['option_page']) ? $_POST['option_page'] : 'options'; $page_referer = false; // Check which of these option groups where modified. switch ($option_page) { case 'options': $page_referer = 'Global'; break; case 'general': /* no_break */ /* no_break */ case 'writing': /* no_break */ /* no_break */ case 'reading': /* no_break */ /* no_break */ case 'discussion': /* no_break */ /* no_break */ case 'media': /* no_break */ /* no_break */ case 'permalink': $page_referer = ucwords($option_page); break; default: $page_referer = 'Common'; break; } if ($page_referer && $options_changed_count > 0) { $message = $page_referer . ' settings changed'; SucuriScanEvent::report_error_event(sprintf('%s: (multiple entries): %s', $message, rtrim($options_changed_simple, ','))); self::notify_event('settings_updated', $message . "<br>\n" . $options_changed_str); } } }