PluginProbe
Patchstack – WordPress & Plugins Security / 2.1.24
Patchstack – WordPress & Plugins Security v2.1.24
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
← All changes | includes/htaccess.php +14 -42 trunk2.1.24 View file →
@@ -19,13 +19,13 @@
19 19 */
20 20 public function __construct( $core ) {
21 21 parent::__construct( $core );
22 22
23 - if ( $this->get_option( 'patchstack_license_free', 0 ) == 1 ) {
23 + if ( $this->get_option( 'patchstack_license_free', 0 ) == 1 || $this->is_community() ) {
24 24 return;
25 25 }
26 26
27 - add_action( 'updated_option', [ $this, 'update_option_extras' ], 10, 3 );
27 + add_action( 'updated_option', array( $this, 'update_option_extras' ), 10, 3 );
28 28 }
29 29
30 30 /**
31 31 * If option is updated, write to .htaccess file.
@@ -35,17 +35,11 @@
35 35 * @param mixed $value
36 36 * @return void
37 37 */
38 38 public function update_option_extras( $option_name, $old_value, $value ) {
39 - if ( !in_array( $option_name, [ 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_pingback_protection', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_trace_and_track', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking', 'patchstack_firewall_custom_rules' ] ) ) {
40 - return;
39 + if ( in_array( $option_name, array( 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_pingback_protection', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_trace_and_track', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking', 'patchstack_firewall_custom_rules' ) ) ) {
40 + $this->plugin->rules->post_firewall_rules();
41 41 }
42 -
43 - if ( $old_value == $value ) {
44 - return;
45 - }
46 -
47 - $this->plugin->rules->post_firewall_rules();
48 42 }
49 43
50 44 /**
51 45 * Get the turned on .htaccess firewall settings.
@@ -52,10 +46,10 @@
52 46 *
53 47 * @return array
54 48 */
55 49 public function get_firewall_rule_settings() {
56 - $settings = [];
57 - $options = [ 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking', 'patchstack_basicscanblock' ];
50 + $settings = array();
51 + $options = array( 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking', 'patchstack_basicscanblock' );
58 52 foreach ( $options as $option ) {
59 53 if ( get_site_option( $option ) ) {
60 54 $settings[] = ( $option == 'patchstack_basicscanblock' ? 'webarx_wpscan_block' : str_replace( 'patchstack_', 'webarx_', $option ) );
61 55 }
@@ -71,9 +65,9 @@
71 65 */
72 66 public function firewall() {
73 67 // Get the firewall state.
74 68 $sum_of_firewall = 0;
75 - foreach ( [ 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_pingback_protection', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_trace_and_track', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking' ] as $option ) {
69 + foreach ( array( 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_pingback_protection', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_trace_and_track', 'patchstack_proxy_comment_posting', 'patchstack_image_hotlinking' ) as $option ) {
76 70 $value = get_site_option( $option, 0 );
77 71 $sum_of_firewall += empty( $value ) ? 0 : 1;
78 72 }
79 73
@@ -78,9 +72,9 @@
78 72 }
79 73
80 74 // Update the options.
81 75 $onoff = $sum_of_firewall > 1 ? 0 : 1;
82 - foreach ( [ 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_block_debug_log_access', 'patchstack_index_views', 'patchstack_proxy_comment_posting' ] as $option ) {
76 + foreach ( array( 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_block_debug_log_access', 'patchstack_index_views', 'patchstack_proxy_comment_posting' ) as $option ) {
83 77 update_site_option( $option, $onoff );
84 78 }
85 79 update_site_option( 'patchstack_block_fake_bots', 0 );
86 80 update_site_option( 'patchstack_image_hotlinking', 0 );
@@ -101,9 +95,9 @@
101 95 * @param string $rules
102 96 * @return void
103 97 */
104 98 public function write_rules_to_htaccess( $rules = '' ) {
105 - if ( ! $this->is_server_supported() || get_site_option( 'patchstack_disable_htaccess', 0 ) || ( defined( 'PS_DISABLE_HTACCESS' ) && PS_DISABLE_HTACCESS ) ) {
99 + if ( ! $this->is_server_supported() || get_site_option( 'patchstack_disable_htaccess', 0 ) ) {
106 100 return false;
107 101 }
108 102
109 103 // Determine if the .htaccess file exists.
@@ -120,9 +114,9 @@
120 114 }
121 115
122 116 // Get the current rules.
123 117 $current = $old = $fs->get_contents( ABSPATH . '.htaccess' );
124 - $current = $this->delete_all_between( '# Patchstack Firewall Start', '# Patchstack Firewall End', $current );
118 + $current = $this->delete_all_between( '# Patchstack Firewall Start', "# Patchstack Firewall End\r\n", $current );
125 119
126 120 // If no rules, then we delete the old ones.
127 121 if ( $rules != '' ) {
128 122 $current = "# Patchstack Firewall Start\r\n<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\n" . $rules . "\r\n</IfModule>\r\n# Patchstack Firewall End\r\n" . $current;
@@ -148,9 +142,9 @@
148 142 * @param string $rules
149 143 * @return boolean
150 144 */
151 145 public function write_to_htaccess( $rules = '' ) {
152 - if ( ! $this->is_server_supported() || get_site_option( 'patchstack_disable_htaccess', 0 ) || ( defined( 'PS_DISABLE_HTACCESS' ) && PS_DISABLE_HTACCESS ) ) {
146 + if ( ! $this->is_server_supported() || get_site_option( 'patchstack_disable_htaccess', 0 ) ) {
153 147 return false;
154 148 }
155 149
156 150 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
@@ -159,22 +153,8 @@
159 153 if ( ! $fs->exists( ABSPATH . '.htaccess' ) ) {
160 154 $fs->touch( ABSPATH . '.htaccess' );
161 155 }
162 156
163 - // Some rule adjustments.
164 - $rewrites = [
165 - 'RedirectMatch 409 .(htaccess|htpasswd|errordocs|logs)$' => 'RedirectMatch 403 \.(htaccess|htpasswd|errordocs|logs)$',
166 - "\n RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in.*$ [NC]" => '',
167 - "\n RewriteCond %{REMOTE_ADDR} !=18.221.197.243" => '',
168 - '^wp-includes/[^/]+.php$' => '^wp-includes/.*\.php$',
169 - 'RewriteRule ^debug*.*log$ index.php?webarx_fpage=502 [L,QSA]' => 'RewriteRule debug\.log$ index.php?webarx_fpage=502 [L,QSA]',
170 - '*.*' => '\.'
171 - ];
172 -
173 - foreach ($rewrites as $find => $replace) {
174 - $rules = str_replace($find, $replace, $rules);
175 - }
176 -
177 157 return $this->plugin->htaccess->self_check( $rules );
178 158 }
179 159
180 160 /**
@@ -182,10 +162,10 @@
182 162 *
183 163 * @return boolean
184 164 */
185 165 public function is_server_supported() {
186 - $server = strtolower( $_SERVER['SERVER_SOFTWARE'] );
187 - foreach ( [ 'apache', 'nginx', 'litespeed' ] as $webserver ) {
166 + $server = strtolower( filter_var( $_SERVER['SERVER_SOFTWARE'], FILTER_SANITIZE_STRING ) );
167 + foreach ( array( 'apache', 'nginx', 'litespeed' ) as $webserver ) {
188 168 if ( strstr( $server, $webserver ) ) {
189 169 return true;
190 170 }
191 171 }
@@ -345,16 +325,8 @@
345 325 if ( $begin_pos === false || $end_pos === false ) {
346 326 return $string;
347 327 }
348 328
349 - $end_pos += strlen( $end );
350 -
351 - // Consume any trailing newline characters so the block is removed cleanly
352 - // regardless of CRLF/LF line endings and repeated writes don't stack blank lines.
353 - while ( isset( $string[ $end_pos ] ) && ( $string[ $end_pos ] === "\r" || $string[ $end_pos ] === "\n" ) ) {
354 - $end_pos++;
355 - }
356 -
357 - $delete = substr( $string, $begin_pos, $end_pos - $begin_pos );
329 + $delete = substr( $string, $begin_pos, ( $end_pos + strlen( $end ) ) - $begin_pos );
358 330 return str_replace( $delete, '', $string );
359 331 }
360 332 }