PluginProbe
NETSENSAI Shield / 1.3
NETSENSAI Shield v1.3
1.6.1 trunk 1.1 1.2 1.3 1.4 1.4.1 1.4.2 1.4.3 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.6.0
netsensai-shield / netsensai-shield.php

netsensai-shield.php in NETSENSAI Shield 1.3, at netsensai-shield.php

390 lines 18.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * NETSENSAI Shield
4 *
5 * Plugin Name: NETSENSAI Shield
6 * Plugin URI: https://www.netsensai.pl/store/
7 * Description: NETSENSAI Shield is a security plugin designed to enhance WordPress site protection by offering essential security features based on best practice principles.
8 * Version: 1.3
9 * Author: Rafał Gierlicki
10 * Author URI: https://www.netsensai.pl
11 * Text Domain: netsensai-shield
12 * Contributors: netsensai
13 * License: GPLv2 or later
14 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
15 */
16
17 // Exit if accessed directly.
18 if ( ! defined( 'ABSPATH' ) ) {
19 exit;
20 }
21
22 /**
23 * Filter admin title so it's never null.
24 *
25 * @param string $title Admin page title.
26 * @return string Modified title.
27 */
28 function ns_shield_fix_admin_title( $title ) {
29 return (string) $title;
30 }
31 add_filter( 'admin_title', 'ns_shield_fix_admin_title', 0, 1 );
32
33 /**
34 * Define tooltip function for login URL explanation.
35 */
36 if ( ! function_exists( 'ns_shield_get_login_url_tooltip' ) ) {
37 function ns_shield_get_login_url_tooltip() {
38 return __(
39 'Changing the login URL helps protect your site from brute-force attacks aimed at the default wp-login.php endpoint. If the default URL remains unchanged, attackers could easily target it to attempt password cracking or credential stuffing attacks.',
40 'netsensai-shield'
41 );
42 }
43 }
44
45 /**
46 * Include plugin function files.
47 */
48 require_once plugin_dir_path( __FILE__ ) . 'includes/login_url_functions.php';
49 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_wp_api_json.php';
50 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_xml_rpc.php';
51 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_app_passwords.php';
52 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_file_editor.php';
53 require_once plugin_dir_path( __FILE__ ) . 'includes/apply_security_headers.php';
54 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_directory_indexing.php';
55 require_once plugin_dir_path( __FILE__ ) . 'includes/disable_default_admin.php';
56 require_once plugin_dir_path( __FILE__ ) . 'includes/apply_hsts_header.php';
57
58 /**
59 * Enqueue styles and scripts for the admin area.
60 */
61 function ns_shield_enqueue_styles_scripts() {
62 wp_enqueue_style(
63 'ns_shield-style',
64 plugin_dir_url( __FILE__ ) . 'assets/style.css',
65 array(),
66 filemtime( plugin_dir_path( __FILE__ ) . 'assets/style.css' )
67 );
68 wp_enqueue_script(
69 'ns_shield-script',
70 plugin_dir_url( __FILE__ ) . 'assets/script.js',
71 array(),
72 '1.0',
73 true
74 );
75 }
76 add_action( 'admin_enqueue_scripts', 'ns_shield_enqueue_styles_scripts' );
77
78 /**
79 * Add settings link on the plugins page.
80 *
81 * @param array $links Array of action links.
82 * @return array Modified links.
83 */
84 function ns_shield_settings_link( $links ) {
85 $settings_link = '<a href="options-general.php?page=secure-options">' . esc_html__( 'Settings', 'netsensai-shield' ) . '</a>';
86 array_unshift( $links, $settings_link );
87 return $links;
88 }
89 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'ns_shield_settings_link' );
90
91 /* =====================
92 SETTINGS PAGE
93 ===================== */
94
95 /**
96 * Display the settings page.
97 */
98 function ns_shield_secure_options_page() {
99 if ( ! current_user_can( 'manage_options' ) ) {
100 wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'netsensai-shield' ) );
101 }
102
103 // Ścieżka do logo
104 $logo_url = plugin_dir_url( __FILE__ ) . 'assets/ns_logo.png';
105
106 // Tworzymy treść dla popupu z możliwości�
107 tłumaczenia.
108 // Używamy __() dla tekstu zawieraj�
109 cego znaczniki <a> aby linki były działaj�
110 ce.
111 $enable_html = sprintf(
112 '<div class="ns-popup-logo-container">
113 <img src="%1$s" alt="%2$s" class="ns-popup-logo" />
114 </div>
115 <div class="ns-popup-text">
116 <p>%3$s</p>
117 <p>%4$s</p>
118 <p>%5$s</p>
119 <p><strong>%6$s</strong> <a href="https://netsensai.pl/store" target="_blank">netsensai.pl/store</a></p>
120 </div>
121 <div class="ns-popup-button-container">
122 <button id="ns-shield-modal-ok" class="ns-modal-ok-button">%7$s</button>
123 </div>',
124 esc_url( $logo_url ),
125 esc_attr__( 'Netsensai Shield Logo', 'netsensai-shield' ),
126 // Używamy __() zamiast esc_html__() dla akapitu ze znacznikami <a>
127 __( 'Your website now achieves top scores in the most popular security scanners. (Check <a href="https://securityheaders.com" target="_blank">securityheaders.com</a> or <a href="https://observatory.mozilla.org" target="_blank">Mozilla Observatory</a>) Great job!', 'netsensai-shield' ),
128 esc_html__( 'But in the PRO Club, we do even more: we detect, block, and support.', 'netsensai-shield' ),
129 esc_html__( 'If an attack occurs, you get 3 months of assistance on us!', 'netsensai-shield' ),
130 esc_html__( 'Check out:', 'netsensai-shield' ),
131 esc_html__( 'OK', 'netsensai-shield' )
132 );
133
134 $disable_html = sprintf(
135 '<h2 style="text-align:center; font-size:1.3em; margin-bottom:10px; color:#000;">%1$s</h2>
136 <p style="font-size:1.1em; line-height:1.4; color:#000;">%2$s</p>',
137 esc_html__( 'Oops...', 'netsensai-shield' ),
138 esc_html__( 'The option has been disabled.', 'netsensai-shield' )
139 );
140 ?>
141 <div id="netsensai-shield-plugin" class="wrap">
142
143 <!-- PRO version banner -->
144 <div style="border: 1px solid #555; padding: 5px; margin: 5px 0; background-color: transparent; text-align: center; color: #fff;">
145 <p style="font-size: 1.2em; font-weight: bold; margin-bottom: 5px;">
146 <?php esc_html_e( 'Upgrade to NETSENSAI-SHIELD PRO for enhanced protection and advanced features.', 'netsensai-shield' ); ?>
147 </p>
148 <p>
149 <?php esc_html_e( 'Get yours now at:', 'netsensai-shield' ); ?>
150 <a href="https://netsensai.pl/store" target="_blank" rel="noopener noreferrer" style="color: #fff; text-decoration: underline;">
151 https://netsensai.pl/store
152 </a>
153 </p>
154 </div>
155
156 <h2><?php echo esc_html__( 'Security Options', 'netsensai-shield' ); ?></h2>
157
158 <!-- Logos display -->
159 <div style="display: flex; align-items: center; gap: 20px; margin-bottom: 10px;">
160 <a href="https://www.netsensai.pl/store/" target="_blank" style="display: flex; align-items: center; gap: 20px;">
161 <img src="<?php echo esc_url( plugin_dir_url( __FILE__ ) . 'assets/ns_logo.png' ); ?>"
162 alt="<?php echo esc_attr__( 'Netsensai-Shield Logo', 'netsensai-shield' ); ?>"
163 style="width: 200px; height: auto; margin-bottom: -20px;">
164 <img src="<?php echo esc_url( plugin_dir_url( __FILE__ ) . 'assets/netsensai.pl_logo.png' ); ?>"
165 alt="<?php echo esc_attr__( 'Netsensai-Logo', 'netsensai-shield' ); ?>"
166 style="width: 220px; height: auto; margin-bottom: -20px;">
167 </a>
168 </div>
169
170 <!-- Konfiguracja modala -->
171 <script type="text/javascript">
172 window.nsShieldModalConfig = {
173 modalShownFor: '',
174 enableContentHTML: <?php echo wp_json_encode( $enable_html ); ?>,
175 disableContentHTML: <?php echo wp_json_encode( $disable_html ); ?>
176 };
177 </script>
178
179 <form method="post" action="options.php">
180 <?php
181 settings_fields( 'ns_shield_options_group' );
182 do_settings_sections( 'secure-options' );
183 submit_button();
184 ?>
185 </form>
186
187 <!-- Include modal popup file from includes/ -->
188 <?php
189 $modal_file = plugin_dir_path( __FILE__ ) . 'includes/modal_popup.php';
190 if ( file_exists( $modal_file ) ) {
191 include $modal_file;
192 }
193 // Jeśli plik nie zostanie znaleziony, nie rób nic – error_log() zostało usunięte.
194 ?>
195 </div> <!-- End of wrap -->
196 <?php
197 }
198
199 /**
200 * Add settings menu in the admin.
201 */
202 function ns_shield_secure_options_menu() {
203 add_options_page(
204 esc_html__( 'Security Options', 'netsensai-shield' ),
205 esc_html__( 'Security Options', 'netsensai-shield' ),
206 'manage_options',
207 'secure-options',
208 'ns_shield_secure_options_page'
209 );
210 }
211 add_action( 'admin_menu', 'ns_shield_secure_options_menu' );
212
213 /**
214 * Register settings and fields.
215 */
216 function ns_shield_secure_options_settings() {
217 register_setting( 'ns_shield_options_group', 'ns_shield_login_url', 'sanitize_text_field' );
218 register_setting( 'ns_shield_options_group', 'ns_shield_login_url_enabled', 'sanitize_text_field' );
219 register_setting( 'ns_shield_options_group', 'ns_shield_wp_api_json', 'sanitize_text_field' );
220 register_setting( 'ns_shield_options_group', 'ns_shield_xml_rpc', 'sanitize_text_field' );
221 register_setting( 'ns_shield_options_group', 'ns_shield_file_editor', 'sanitize_text_field' );
222 register_setting( 'ns_shield_options_group', 'ns_shield_app_passwords', 'absint' );
223 register_setting( 'ns_shield_options_group', 'ns_shield_security_headers', 'sanitize_text_field' );
224 register_setting( 'ns_shield_options_group', 'ns_shield_directory_indexing', 'sanitize_text_field' );
225 register_setting( 'ns_shield_options_group', 'ns_shield_default_admin', 'absint' );
226 register_setting( 'ns_shield_options_group', 'ns_shield_new_admin_login', 'sanitize_text_field' );
227 register_setting( 'ns_shield_options_group', 'ns_shield_hsts', 'sanitize_text_field' );
228 register_setting( 'ns_shield_options_group', 'ns_shield_debug', 'sanitize_text_field' );
229 // Register new settings for CSP headers.
230 register_setting( 'ns_shield_options_group', 'ns_shield_csp_header_light', 'intval' );
231 register_setting( 'ns_shield_options_group', 'ns_shield_csp_header_hard', 'ns_shield_sanitize_csp_hard' );
232
233 // Level 1: Basic Security (login URL options etc.)
234 add_settings_section( 'ns_shield_level_1', esc_html__( 'Level 1: Basic Security', 'netsensai-shield' ), null, 'secure-options' );
235 add_settings_field( 'ns_shield_login_url', esc_html__( 'Change Login URL', 'netsensai-shield' ), 'ns_shield_change_login_url', 'secure-options', 'ns_shield_level_1' );
236 add_settings_field( 'ns_shield_default_admin', esc_html__( 'Disable Default Admin', 'netsensai-shield' ), 'ns_shield_disable_default_admin', 'secure-options', 'ns_shield_level_1' );
237 add_settings_field( 'ns_shield_xml_rpc', esc_html__( 'Disable XML-RPC', 'netsensai-shield' ), 'ns_shield_field_xml_rpc', 'secure-options', 'ns_shield_level_1' );
238
239 // Level 2: Intermediate Security
240 add_settings_section( 'ns_shield_level_2', esc_html__( 'Level 2: Intermediate Security', 'netsensai-shield' ), null, 'secure-options' );
241 add_settings_field( 'ns_shield_wp_api_json', esc_html__( 'Disable WP API JSON', 'netsensai-shield' ), 'ns_shield_field_wp_api_json', 'secure-options', 'ns_shield_level_2' );
242 add_settings_field( 'ns_shield_file_editor', esc_html__( 'Disable File Editor', 'netsensai-shield' ), 'ns_shield_field_file_editor', 'secure-options', 'ns_shield_level_2' );
243 add_settings_field( 'ns_shield_app_passwords', esc_html__( 'Disable WordPress Application Passwords', 'netsensai-shield' ), 'ns_shield_field_app_passwords', 'secure-options', 'ns_shield_level_2' );
244
245 // Level 3: Advanced Security
246 add_settings_section( 'ns_shield_level_3', esc_html__( 'Level 3: Advanced Security', 'netsensai-shield' ), null, 'secure-options' );
247 add_settings_field( 'ns_shield_directory_indexing', esc_html__( 'Disable Directory Indexing', 'netsensai-shield' ), 'ns_shield_field_directory_indexing', 'secure-options', 'ns_shield_level_3' );
248 add_settings_field( 'ns_shield_hsts', esc_html__( 'Enable HSTS', 'netsensai-shield' ), 'ns_shield_field_hsts', 'secure-options', 'ns_shield_level_3' );
249 add_settings_field( 'ns_shield_security_headers', esc_html__( 'Apply Security Headers', 'netsensai-shield' ), 'ns_shield_field_security_headers', 'secure-options', 'ns_shield_level_3' );
250 }
251 add_action( 'admin_init', 'ns_shield_secure_options_settings' );
252
253 /* =====================
254 FIELD CALLBACKS
255 ===================== */
256
257 function ns_shield_field_xml_rpc() {
258 $checked = get_option( 'ns_shield_xml_rpc', 0 ) ? 'checked' : '';
259 echo '<label class="switch">';
260 echo '<input type="checkbox" name="ns_shield_xml_rpc" value="1" ' . esc_attr( $checked ) . '>';
261 echo '<span class="slider round"></span>';
262 echo '<div class="tooltip">' .
263 esc_html__(
264 'Disabling XML-RPC blocks unauthorized remote access attempts, which can enhance security. If XML-RPC remains enabled, hackers might attempt to perform DDoS attacks by sending multiple requests or brute-force password attacks to gain control over your site.',
265 'netsensai-shield'
266 ) .
267 '</div>';
268 echo '</label>';
269 }
270
271 function ns_shield_field_wp_api_json() {
272 $checked = get_option( 'ns_shield_wp_api_json', 0 ) ? 'checked' : '';
273 echo '<label class="switch">';
274 echo '<input type="checkbox" name="ns_shield_wp_api_json" value="1" ' . esc_attr( $checked ) . '>';
275 echo '<span class="slider round"></span>';
276 echo '<div class="tooltip">' .
277 esc_html__(
278 'Disabling WP API JSON can protect your site from unauthorized access to sensitive data through the API. If left enabled, hackers may exploit WP API JSON to gather information about your site’s structure or perform enumeration attacks on users, which can lead to brute-force attacks.',
279 'netsensai-shield'
280 ) .
281 '</div>';
282 echo '</label>';
283 }
284
285 function ns_shield_field_file_editor() {
286 $checked = get_option( 'ns_shield_file_editor', 0 ) ? 'checked' : '';
287 echo '<label class="switch">';
288 echo '<input type="checkbox" name="ns_shield_file_editor" value="1" ' . esc_attr( $checked ) . '>';
289 echo '<span class="slider round"></span>';
290 echo '<div class="tooltip">' .
291 esc_html__(
292 'Disabling the file editor in the WP dashboard prevents unauthorized or accidental code changes. If left enabled, attackers who gain access to your admin panel could inject malicious code into your theme or plugin files, leading to a defacement of the site or the deployment of malware.',
293 'netsensai-shield'
294 ) .
295 '</div>';
296 echo '</label>';
297 }
298
299 function ns_shield_field_app_passwords() {
300 $checked = get_option( 'ns_shield_app_passwords', 0 ) ? 'checked' : '';
301 echo '<label class="switch">';
302 echo '<input type="checkbox" name="ns_shield_app_passwords" value="1" ' . esc_attr( $checked ) . '>';
303 echo '<span class="slider round"></span>';
304 echo '<div class="tooltip">' .
305 esc_html__(
306 'Disabling application passwords secures against creating unauthorized accesses to your site’s API. If left enabled, hackers may exploit application passwords to gain persistent access to your site, enabling them to execute unauthorized API requests or even escalate their privileges.',
307 'netsensai-shield'
308 ) .
309 '</div>';
310 echo '</label>';
311 }
312
313 function ns_shield_field_security_headers() {
314 $checked = get_option( 'ns_shield_security_headers', 0 ) ? 'checked' : '';
315 echo '<label class="switch">';
316 echo '<input type="checkbox" name="ns_shield_security_headers" id="ns-shield-preload-checkbox" value="1" ' . esc_attr( $checked ) . '>';
317 echo '<span class="slider round"></span>';
318 echo '<div class="tooltip">' .
319 esc_html__(
320 'Applying security headers can protect your site from XSS attacks and other threats. Without them, your site could be vulnerable to cross-site scripting (XSS) attacks or clickjacking, allowing attackers to steal sensitive data or trick users into executing malicious actions.',
321 'netsensai-shield'
322 ) .
323 '</div>';
324 echo '</label>';
325 }
326
327 /**
328 * FIELD CALLBACK: Directory Indexing.
329 */
330 function ns_shield_field_directory_indexing() {
331 $checked = get_option( 'ns_shield_directory_indexing', 0 ) ? 'checked' : '';
332 echo '<label class="switch">';
333 echo '<input type="checkbox" name="ns_shield_directory_indexing" value="1" ' . esc_attr( $checked ) . '>';
334 echo '<span class="slider round"></span>';
335 echo '<div class="tooltip">' .
336 esc_html__(
337 'Directory indexing allows attackers to list and access files in directories that lack an index file, exposing sensitive files and configurations. If directory indexing is not disabled, attackers can execute Directory Traversal attacks, gaining access to configuration files, logs, or even databases.',
338 'netsensai-shield'
339 ) .
340 '</div>';
341 echo '</label>';
342 }
343
344 /**
345 * FIELD CALLBACK: HSTS.
346 */
347 function ns_shield_field_hsts() {
348 $checked = get_option( 'ns_shield_hsts', 0 ) ? 'checked' : '';
349 echo '<label class="switch">';
350 echo '<input type="checkbox" name="ns_shield_hsts" value="1" ' . esc_attr( $checked ) . '>';
351 echo '<span class="slider round"></span>';
352 echo '<div class="tooltip">' .
353 esc_html__(
354 'HTTP Strict Transport Security (HSTS) enforces HTTPS, ensuring that all communication between the browser and the server is encrypted. This is critical for protecting sensitive user data and preventing man-in-the-middle attacks.',
355 'netsensai-shield'
356 ) .
357 '</div>';
358 echo '</label>';
359 }
360
361 /**
362 * Flush rewrite rules after settings update.
363 */
364 function ns_shield_flush_rewrite_rules_on_settings_update() {
365 if ( is_admin() && isset( $_GET['settings-updated'] ) && 'true' === $_GET['settings-updated'] ) {
366 flush_rewrite_rules();
367 }
368 }
369 add_action( 'admin_init', 'ns_shield_flush_rewrite_rules_on_settings_update', 20 );
370
371 /**
372 * Flush rewrite rules on plugin activation.
373 */
374 function ns_shield_activation_flush() {
375 if ( function_exists( 'ns_shield_add_rewrite_rule' ) ) {
376 ns_shield_add_rewrite_rule();
377 }
378 flush_rewrite_rules();
379 }
380 register_activation_hook( __FILE__, 'ns_shield_activation_flush' );
381
382 /**
383 * Flush rewrite rules on plugin deactivation.
384 */
385 function ns_shield_deactivation_flush() {
386 flush_rewrite_rules();
387 }
388 register_deactivation_hook( __FILE__, 'ns_shield_deactivation_flush' );
389 ?>
390