PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.1
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / pages / page-mainwp-security-issues.php

page-mainwp-security-issues.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.1, at pages/page-mainwp-security-issues.php

411 lines 22.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Security Issues page
4 *
5 * This page is used to manage child site security issues.
6 *
7 * @package MainWP/Securtiy_Issues
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_Security_Issues
19 *
20 * Detect, display & fix known Security Issues.
21 */
22 class MainWP_Security_Issues { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23
24 /**
25 * Method get_class_name()
26 *
27 * @return string __CLASS__ Class Name
28 */
29 public static function get_class_name() {
30 return __CLASS__;
31 }
32
33 /**
34 * Method render()
35 *
36 * @param null $website Child Site ID.
37 *
38 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
39 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
40 */
41 public static function render( $website = null ) {
42
43 if ( empty( $website ) ) {
44 $id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
45 if ( ! $id ) {
46 return;
47 }
48 $website = MainWP_DB::instance()->get_website_by_id( $id );
49 }
50
51 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
52 return;
53 }
54 ?>
55 <table class="ui table" id="mainwp-security-issues-table">
56 <thead>
57 <tr>
58 <th scope="col" class="center aligned collapsing"></th>
59 <th scope="col"><?php esc_html_e( 'Site Hardening Checks', 'mainwp' ); ?></th>
60 <th scope="col" class="collapsing"></th>
61 </tr>
62 </thead>
63 <tbody>
64 <tr>
65 <td>
66 <span id="wp_uptodate_loading"><i class="notched circle big loading icon"></i></span>
67 <span id="wp_uptodate_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
68 <span id="wp_uptodate_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
69 </td>
70 <td>
71 <div class="ui small header">
72 <?php esc_html_e( 'WordPress Version', 'mainwp' ); ?>
73 <div class="sub header">
74 <div id="wp_uptodate-status-nok" style="display: none;"><?php esc_html_e( 'WordPress is not up to date.', 'mainwp' ); ?></div>
75 <div id="wp_uptodate-status-ok" style="display: none;"><?php esc_html_e( 'WordPress is up to date.', 'mainwp' ); ?></div>
76 </div>
77 </div>
78 </td>
79 <td>
80 <span id="wp_uptodate_fix" style="display: none"><a href="#" onClick="updatesoverview_global_upgrade_all('wp'); return false;" class="ui mini green fluid button" data-inverted="" data-position="left center" data-tooltip="<?php esc_attr_e( 'Click here to update the WordPress core on the site.', 'mainwp' ); ?>"><?php esc_html_e( 'Update WordPress', 'mainwp' ); ?></a></span>
81 </td>
82 </tr>
83
84 <tr>
85 <td>
86 <span id="phpversion_matched_loading"><i class="notched circle big loading icon"></i></span>
87 <span id="phpversion_matched_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
88 <span id="phpversion_matched_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
89 </td>
90 <td>
91 <div class="ui small header">
92 <?php esc_html_e( 'PHP Version', 'mainwp' ); ?>
93 <div class="sub header">
94 <div id="phpversion_matched-status-nok" style="display: none;"><?php esc_html_e( 'PHP version older than 8.0 reached end of development and no longer receive security updates.', 'mainwp' ); ?></div>
95 <div id="phpversion_matched-status-ok" style="display: none;"><?php esc_html_e( 'PHP version is up to date.', 'mainwp' ); ?></div>
96 </div>
97 </div>
98 </td>
99 <td></td>
100 </tr>
101
102 <tr>
103 <td>
104 <span id="php_reporting_loading"><i class="notched circle big loading icon"></i></span>
105 <span id="php_reporting_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
106 <span id="php_reporting_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
107 </td>
108 <td>
109 <div class="ui small header">
110 <?php esc_html_e( 'PHP Error Reporting', 'mainwp' ); ?>
111 <div class="sub header">
112 <div id="php_reporting-status-nok" style="display: none;"><?php esc_html_e( 'PHP Error reporting is not disabled. Error messages can reveal sensitive details.', 'mainwp' ); ?></div>
113 <div id="php_reporting-status-ok" style="display: none;"><?php esc_html_e( 'PHP Error reporting is disabled.', 'mainwp' ); ?></div>
114 </div>
115 </div>
116 </td>
117 <td>
118 <span id="php_reporting_fix" style="display: none"><a href="#" class="ui mini fluid green button"> <?php esc_html_e( 'Disable PHP Error Reporting', 'mainwp' ); ?></a></span>
119 <span id="php_reporting_unfix" style="display: none"><a href="#" class="ui mini fluid button"><?php esc_html_e( 'Reenable PHP Error Reporting', 'mainwp' ); ?></a></span>
120 </td>
121 </tr>
122
123 <tr>
124 <td>
125 <span id="db_reporting_loading"><i class="notched circle big loading icon"></i></span>
126 <span id="db_reporting_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
127 <span id="db_reporting_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
128 </td>
129 <td>
130 <div class="ui small header">
131 <?php esc_html_e( 'Database Error Reporting', 'mainwp' ); ?>
132 <div class="sub header">
133 <div id="db_reporting-status-nok" style="display: none;"><?php esc_html_e( 'Database Error reporting is not disabled. Error messages can reveal sensitive details.', 'mainwp' ); ?></div>
134 <div id="db_reporting-status-ok" style="display: none;"><?php esc_html_e( 'Database Error reporting is disabled.', 'mainwp' ); ?></div>
135 </div>
136 </div>
137 </td>
138 <td>
139 <span id="db_reporting_fix" style="display: none"><a href="#" class="ui mini fluid green button"><?php esc_html_e( 'Disable DB Error Reporting', 'mainwp' ); ?></a></span>
140 <span id="db_reporting_unfix" style="display: none"><a href="#" class="ui mini fluid button"><?php esc_html_e( 'Reenable DB Error Reporting', 'mainwp' ); ?></a></span>
141 </td>
142 </tr>
143
144 <tr>
145 <td>
146 <span id="sslprotocol_loading"><i class="notched circle big loading icon"></i></span>
147 <span id="sslprotocol_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
148 <span id="sslprotocol_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
149 </td>
150 <td>
151 <div class="ui small header">
152 <?php esc_html_e( 'SSL Protocol', 'mainwp' ); ?>
153 <div class="sub header">
154 <div id="sslprotocol-status-nok" style="display: none;"><?php esc_html_e( 'SSL Protocol is not in place.', 'mainwp' ); ?></div>
155 <div id="sslprotocol-status-ok" style="display: none;"><?php esc_html_e( 'SSL Protocol is in place.', 'mainwp' ); ?></div>
156 </div>
157 </div>
158 </td>
159 <td></td>
160 </tr>
161
162 <tr>
163 <td>
164 <span id="debug_disabled_loading"><i class="notched circle big loading icon"></i></span>
165 <span id="debug_disabled_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
166 <span id="debug_disabled_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
167 </td>
168 <td>
169 <div class="ui small header">
170 <?php esc_html_e( 'Debug Mode', 'mainwp' ); ?>
171 <div class="sub header">
172 <div id="debug_disabled-status-nok" style="display: none;"><?php esc_html_e( 'WP Debug mode is not disabled. Error messages can reveal sensitive details.', 'mainwp' ); ?></div>
173 <div id="debug_disabled-status-ok" style="display: none;"><?php esc_html_e( 'WP Debug mode is disabled.', 'mainwp' ); ?></div>
174 </div>
175 </div>
176 </td>
177 <td></td>
178 </tr>
179
180 <tr>
181 <td>
182 <span id="sec_outdated_plugins_loading"><i class="notched circle big loading icon"></i></span>
183 <span id="sec_outdated_plugins_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
184 <span id="sec_outdated_plugins_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
185 </td>
186 <td>
187 <div class="ui small header">
188 <?php esc_html_e( 'Outdated Plugins', 'mainwp' ); ?>
189 <div class="sub header">
190 <div id="sec_outdated_plugins-status-nok" style="display: none;"><?php esc_html_e( 'Plugins are not up to date. Outdated plugins can contain known vulnerabilities that attackers may exploit.', 'mainwp' ); ?></div>
191 <div id="sec_outdated_plugins-status-ok" style="display: none;"><?php esc_html_e( 'Plugins are up to date.', 'mainwp' ); ?></div>
192 </div>
193 </div>
194 </td>
195 <td>
196 <span id="sec_outdated_plugins_fix" style="display: none"><a href="admin.php?page=managesites&updateid=<?php echo intval( $website->id ); ?>" class="ui mini basic button"><?php esc_html_e( 'Manage Updates', 'mainwp' ); ?></a></span>
197 </td>
198 </tr>
199
200 <tr>
201 <td>
202 <span id="sec_inactive_plugins_loading"><i class="notched circle big loading icon"></i></span>
203 <span id="sec_inactive_plugins_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
204 <span id="sec_inactive_plugins_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
205 </td>
206 <td>
207 <div class="ui small header">
208 <?php esc_html_e( 'Inactive Plugins', 'mainwp' ); ?>
209 <div class="sub header">
210 <div id="sec_inactive_plugins-status-nok" style="display: none;"><?php esc_html_e( 'Inactive plugins detected. Removing unused plugins minimizes the risk of hidden vulnerabilities that could be exploited.', 'mainwp' ); ?></div>
211 <div id="sec_inactive_plugins-status-ok" style="display: none;"><?php esc_html_e( 'No inactive plugins.', 'mainwp' ); ?></div>
212 </div>
213 </div>
214 </td>
215 <td>
216 <span id="sec_inactive_plugins_fix" style="display: none"><a href="admin.php?page=PluginsManage" class="ui mini basic button"><?php esc_html_e( 'Manage Plugins', 'mainwp' ); ?></a></span>
217 </td>
218 </tr>
219
220 <tr>
221 <td>
222 <span id="sec_outdated_themes_loading"><i class="notched circle big loading icon"></i></span>
223 <span id="sec_outdated_themes_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
224 <span id="sec_outdated_themes_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
225 </td>
226 <td>
227 <div class="ui small header">
228 <?php esc_html_e( 'Outdated Themes', 'mainwp' ); ?>
229 <div class="sub header">
230 <div id="sec_outdated_themes-status-nok" style="display: none;"><?php esc_html_e( 'Themes are not up to date. Outdated themes can contain known vulnerabilities that attackers may exploit.', 'mainwp' ); ?></div>
231 <div id="sec_outdated_themes-status-ok" style="display: none;"><?php esc_html_e( 'Themes are up to date.', 'mainwp' ); ?></div>
232 </div>
233 </div>
234 </td>
235 <td>
236 <span id="sec_outdated_themes_fix" style="display: none"><a href="admin.php?page=managesites&updateid=<?php echo intval( $website->id ); ?>&tab=themes-updates" class="ui mini basic button"><?php esc_html_e( 'Manage Updates', 'mainwp' ); ?></a></span>
237 </td>
238 </tr>
239
240 <tr>
241 <td>
242 <span id="sec_inactive_themes_loading"><i class="notched circle big loading icon"></i></span>
243 <span id="sec_inactive_themes_ok" style="display: none;"><span class="ui small green label"><?php esc_html_e( 'Good', 'mainwp' ); ?></span></span>
244 <span id="sec_inactive_themes_nok" style="display: none;"><span class="ui small red label"><?php esc_html_e( 'Bad', 'mainwp' ); ?></span></span>
245 </td>
246 <td>
247 <div class="ui small header">
248 <?php esc_html_e( 'Inactive Themes', 'mainwp' ); ?>
249 <div class="sub header">
250 <div id="sec_inactive_themes-status-nok" style="display: none;"><?php esc_html_e( 'Inactive themes detected. Removing unused themes minimizes the risk of hidden vulnerabilities that could be exploited.', 'mainwp' ); ?></div>
251 <div id="sec_inactive_themes-status-ok" style="display: none;"><?php esc_html_e( 'No inactive themes.', 'mainwp' ); ?></div>
252 </div>
253 </div>
254 </td>
255 <td>
256 <span id="sec_inactive_themes_fix" style="display: none"><a href="admin.php?page=ThemesManage" class="ui mini basic button"><?php esc_html_e( 'Manage Themes', 'mainwp' ); ?></a></span>
257 </td>
258 </tr>
259
260 </tbody>
261 </table>
262
263
264 <input type="hidden" id="securityIssueSite" value="<?php echo intval( $website->id ); ?>"/>
265 <div id="wp_upgrades">
266 <div updated="-1" site_id="<?php echo intval( $website->id ); ?>" site_name="<?php echo esc_attr( $website->name ); ?>" ></div>
267 </div>
268 <?php
269 }
270
271
272 /**
273 * Method Fetch Security Issues
274 *
275 * Fetch stored known Child Site Security Issues from DB that were found during Sync.
276 *
277 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
278 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
279 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
280 */
281 public static function fetch_security_issues() {
282 $id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
283 if ( ! $id ) {
284 return '';
285 }
286 $website = MainWP_DB::instance()->get_website_by_id( $id );
287
288 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
289 return '';
290 }
291
292 $information = MainWP_Connect::fetch_url_authed( $website, 'security' );
293
294 /**
295 * Filters security issues
296 *
297 * Filters the default security checks and enables user to disable certain checks.
298 *
299 * @param bool false Whether security issues should be filtered.
300 * @param object $information Object containing data from che chid site related to security issues.
301 * Available options: 'db_reporting', 'php_reporting'.
302 * @param object $website Object containing child site data.
303 *
304 * @since 4.1
305 */
306 $filterStats = apply_filters( 'mainwp_security_issues_stats', false, $information, $website );
307 if ( false !== $filterStats && is_array( $filterStats ) ) {
308 $information = array_merge( $information, $filterStats );
309 }
310 return $information;
311 }
312
313 /**
314 * Method Fix Security Issues
315 *
316 * Fix the selected security issue.
317 *
318 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
319 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
320 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
321 */
322 public static function fix_security_issue() { // phpcs:ignore -- NOSONAR - complex.
323 $id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
324 if ( ! $id ) {
325 return '';
326 }
327 $website = MainWP_DB::instance()->get_website_by_id( $id );
328
329 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
330 return '';
331 }
332
333 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
334 return '';
335 }
336
337 $skip_features = array(
338 'db_reporting',
339 'php_reporting',
340 'wp_uptodate',
341 'phpversion_matched',
342 'sslprotocol',
343 'debug_disabled',
344 );
345
346 /**
347 * Filters security issues from fixing
348 *
349 * Filters the default security checks and enables user to disable certain issues from being fixed by using the Fix All button.
350 *
351 * @param bool false Whether security issues should be filtered.
352 * @param object $skip_features Object containing data from che chid site related to security issues.
353 * Available options: 'db_reporting', 'php_reporting'.
354 * @param object $website Object containing child site data.
355 *
356 * @since 4.1
357 */
358 $skip_features = apply_filters( 'mainwp_security_post_data', false, $skip_features, $website );
359
360 $feature = isset( $_REQUEST['feature'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['feature'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
361 $post_data = array( 'feature' => $feature );
362 if ( ! empty( $skip_features ) && is_array( $skip_features ) ) {
363 $post_data['skip_features'] = $skip_features;
364 }
365
366 $unset_scripts = apply_filters( 'mainwp_unset_security_scripts_stylesheets', true );
367 if ( $unset_scripts ) {
368 if ( ! isset( $post_data['skip_features'] ) ) {
369 $post_data['skip_features'] = array();
370 }
371
372 if ( ! in_array( 'versions', $post_data['skip_features'] ) ) {
373 $post_data['skip_features'][] = 'versions';
374 }
375 }
376
377 $information = MainWP_Connect::fetch_url_authed( $website, 'securityFix', $post_data );
378 return $information;
379 }
380
381 /**
382 * Method un-Fix Security Issues
383 *
384 * Un-Fix the selected security issue.
385 *
386 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
387 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
388 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
389 */
390 public static function unfix_security_issue() {
391 $id = isset( $_REQUEST['id'] ) ? intval( $_REQUEST['id'] ) : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
392 if ( ! $id ) {
393 return '';
394 }
395 $website = MainWP_DB::instance()->get_website_by_id( $id );
396
397 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
398 return '';
399 }
400
401 if ( '' !== $website->sync_errors || MainWP_System_Utility::is_suspended_site( $website ) ) {
402 return '';
403 }
404
405 $feature = isset( $_REQUEST['feature'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['feature'] ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Recommended
406
407 $information = MainWP_Connect::fetch_url_authed( $website, 'securityUnFix', array( 'feature' => $feature ) );
408 return $information;
409 }
410 }
411