VaultPress - Version 1.9.7

Version Description

  • 11 December 2018 =
  • Update firewall IP detection rules to autodetect various reverse proxy setups
Download this release

Release Info

Developer thingalon
Plugin Icon 128x128 VaultPress
Version 1.9.7
Comparing to
See all releases

Code changes from version 1.9.6 to 1.9.7

Files changed (2) hide show
  1. readme.txt +9 -7
  2. vaultpress.php +91 -31
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: automattic, apokalyptik, briancolinger, josephscott, shaunandrews, xknown, thingalon, annezazu, rachelsquirrel
3
  Tags: security, malware, virus, archive, back up, back ups, backup, backups, scanning, restore, wordpress backup, site backup, website backup
4
  Requires at least: 3.2
5
- Tested up to: 4.9
6
- Stable tag: 1.9.6
7
  License: GPLv2
8
 
9
  VaultPress is a subscription service offering real-time backup, automated security scanning, and support from WordPress experts.
@@ -47,17 +47,19 @@ A VaultPress subscription is for a single WordPress site. You can purchase addit
47
  Yes, VaultPress supports Multisite installs. Each site will require its own subscription.
48
 
49
  == Changelog ==
50
- = 1.9.6 - 17 August 2018
 
 
 
51
  * Limit _vp_ai_ping_% entries to improve stability when a site gets disconnected from VaultPress.com
52
 
53
- == Changelog ==
54
- = 1.9.5 - 2 February 2018
55
  * Removing activation notice
56
 
57
- = 1.9.4 - 15 November 2017
58
  * Error handling improvements in the scanner
59
 
60
- = 1.9.3 - 9 November 2017
61
  * Compatibility update
62
  * Send a better user-agent string to VaultPress servers
63
 
2
  Contributors: automattic, apokalyptik, briancolinger, josephscott, shaunandrews, xknown, thingalon, annezazu, rachelsquirrel
3
  Tags: security, malware, virus, archive, back up, back ups, backup, backups, scanning, restore, wordpress backup, site backup, website backup
4
  Requires at least: 3.2
5
+ Tested up to: 5.0
6
+ Stable tag: 1.9.7
7
  License: GPLv2
8
 
9
  VaultPress is a subscription service offering real-time backup, automated security scanning, and support from WordPress experts.
47
  Yes, VaultPress supports Multisite installs. Each site will require its own subscription.
48
 
49
  == Changelog ==
50
+ = 1.9.7 - 11 December 2018 =
51
+ * Update firewall IP detection rules to autodetect various reverse proxy setups
52
+
53
+ = 1.9.6 - 17 August 2018 =
54
  * Limit _vp_ai_ping_% entries to improve stability when a site gets disconnected from VaultPress.com
55
 
56
+ = 1.9.5 - 2 February 2018 =
 
57
  * Removing activation notice
58
 
59
+ = 1.9.4 - 15 November 2017 =
60
  * Error handling improvements in the scanner
61
 
62
+ = 1.9.3 - 9 November 2017 =
63
  * Compatibility update
64
  * Send a better user-agent string to VaultPress servers
65
 
vaultpress.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: VaultPress
4
  * Plugin URI: http://vaultpress.com/?utm_source=plugin-uri&utm_medium=plugin-description&utm_campaign=1.0
5
  * Description: Protect your content, themes, plugins, and settings with <strong>realtime backup</strong> and <strong>automated security scanning</strong> from <a href="http://vaultpress.com/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">VaultPress</a>. Activate, enter your registration key, and never worry again. <a href="http://vaultpress.com/help/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">Need some help?</a>
6
- * Version: 1.9.6
7
  * Author: Automattic
8
  * Author URI: http://vaultpress.com/?utm_source=author-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
9
  * License: GPL2+
@@ -18,7 +18,7 @@ class VaultPress {
18
  var $option_name = 'vaultpress';
19
  var $auto_register_option = 'vaultpress_auto_register';
20
  var $db_version = 4;
21
- var $plugin_version = '1.9.6';
22
 
23
  function __construct() {
24
  register_activation_hook( __FILE__, array( $this, 'activate' ) );
@@ -182,6 +182,18 @@ class VaultPress {
182
  return '';
183
  }
184
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  if ( isset( $this->options[$key] ) )
186
  return $this->options[$key];
187
 
@@ -189,11 +201,25 @@ class VaultPress {
189
  }
190
 
191
  function update_option( $key, $value ) {
 
 
 
 
 
 
 
 
 
 
192
  $this->options[$key] = $value;
193
  $this->update_options();
194
  }
195
 
196
  function delete_option( $key ) {
 
 
 
 
197
  unset( $this->options[$key] );
198
  $this->update_options();
199
  }
@@ -1088,14 +1114,17 @@ class VaultPress {
1088
 
1089
  // if we're running a connection test we don't want to run it a second time
1090
  $connection_test = $this->get_option( 'connection_test' );
1091
- if ( $connection_test )
1092
  return true;
1093
 
1094
  // force update firewall settings
1095
  $this->update_firewall();
1096
 
 
 
 
 
1097
  // initial connection test to server
1098
- $this->update_option( 'connection_test', true );
1099
  $this->delete_option( 'allow_forwarded_for' );
1100
  $host = ( ! empty( $_SERVER['HTTP_HOST'] ) ) ? $_SERVER['HTTP_HOST'] : parse_url( $this->site_url(), PHP_URL_HOST );
1101
  $connect = $this->contact_service( 'test', array( 'host' => $host, 'uri' => $_SERVER['REQUEST_URI'], 'ssl' => is_ssl() ) );
@@ -1127,26 +1156,19 @@ class VaultPress {
1127
  }
1128
 
1129
  // test connection between the site and the servers
1130
- $connect = (string)$this->contact_service( 'test', array( 'type' => 'connect' ) );
1131
  if ( 'ok' != $connect ) {
1132
-
1133
- // still not working so see if we're behind a load balancer
1134
- $this->update_option( 'allow_forwarded_for', true );
1135
- $connect = (string)$this->contact_service( 'test', array( 'type' => 'firewall-off' ) );
1136
-
1137
- if ( 'ok' != $connect ) {
1138
- if ( 'error' == $connect ) {
1139
- $this->update_option( 'connection_error_code', -1 );
1140
- $this->update_option( 'connection_error_message', sprintf( __( 'The VaultPress servers cannot connect to your site. Please check that your site is visible over the Internet and there are no firewall or load balancer settings on your server that might be blocking the communication. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1141
- } elseif ( !empty( $connect['faultCode'] ) ) {
1142
- $this->update_option( 'connection_error_code', $connect['faultCode'] );
1143
- $this->update_option( 'connection_error_message', $connect['faultString'] );
1144
- }
1145
-
1146
- $this->update_option( 'connection', time() );
1147
- $this->delete_option( 'connection_test' );
1148
- return false;
1149
  }
 
 
 
 
1150
  }
1151
 
1152
  // successful connection established
@@ -1911,27 +1933,65 @@ JS;
1911
  }
1912
 
1913
  // Figure out possible remote IPs
1914
- if ( $this->get_option( 'allow_forwarded_for') && !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
1915
- $remote_ips = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );
1916
-
1917
  if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
1918
- $remote_ips[] = $_SERVER['REMOTE_ADDR'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1919
 
1920
  if ( empty( $remote_ips ) ) {
1921
  $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
1922
  return false;
1923
  }
1924
-
1925
- foreach ( $remote_ips as $ip ) {
1926
- $ip = preg_replace( '#^::(ffff:)?#', '', $ip );
1927
- if ( $cidr = $this->ip_in_cidrs( $ip, $cidrs ) ) {
1928
- return true;
 
 
 
 
 
 
 
 
1929
  }
1930
  }
1931
 
1932
  $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
1933
  return false;
1934
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1935
 
1936
  function do_c_block_firewall() {
1937
  // Perform the firewall check by class-c ip blocks
3
  * Plugin Name: VaultPress
4
  * Plugin URI: http://vaultpress.com/?utm_source=plugin-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
5
  * Description: Protect your content, themes, plugins, and settings with <strong>realtime backup</strong> and <strong>automated security scanning</strong> from <a href="http://vaultpress.com/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">VaultPress</a>. Activate, enter your registration key, and never worry again. <a href="http://vaultpress.com/help/?utm_source=wp-admin&amp;utm_medium=plugin-description&amp;utm_campaign=1.0" rel="nofollow">Need some help?</a>
6
+ * Version: 1.9.7
7
  * Author: Automattic
8
  * Author URI: http://vaultpress.com/?utm_source=author-uri&amp;utm_medium=plugin-description&amp;utm_campaign=1.0
9
  * License: GPL2+
18
  var $option_name = 'vaultpress';
19
  var $auto_register_option = 'vaultpress_auto_register';
20
  var $db_version = 4;
21
+ var $plugin_version = '1.9.7';
22
 
23
  function __construct() {
24
  register_activation_hook( __FILE__, array( $this, 'activate' ) );
182
  return '';
183
  }
184
 
185
+ // allow_forwarded_for can be overrided by config, or stored in or out of the vp option
186
+ if ( 'allow_forwarded_for' === $key ) {
187
+ if ( defined( 'ALLOW_FORWARDED_FOR' ) ) {
188
+ return ALLOW_FORWARDED_FOR;
189
+ }
190
+
191
+ $standalone_option = get_option( 'vaultpress_allow_forwarded_for' );
192
+ if ( ! empty( $standalone_option ) ) {
193
+ return $standalone_option;
194
+ }
195
+ }
196
+
197
  if ( isset( $this->options[$key] ) )
198
  return $this->options[$key];
199
 
201
  }
202
 
203
  function update_option( $key, $value ) {
204
+ if ( 'allow_forwarded_for' === $key ) {
205
+ update_option( 'vaultpress_allow_forwarded_for', $value );
206
+
207
+ if ( isset( $this->options[ $key ] ) ) {
208
+ unset( $this->options[ $key ] );
209
+ $this->update_options();
210
+ }
211
+ return;
212
+ }
213
+
214
  $this->options[$key] = $value;
215
  $this->update_options();
216
  }
217
 
218
  function delete_option( $key ) {
219
+ if ( 'allow_forwarded_for' === $key ) {
220
+ delete_option( 'vaultpress_allow_forwarded_for' );
221
+ }
222
+
223
  unset( $this->options[$key] );
224
  $this->update_options();
225
  }
1114
 
1115
  // if we're running a connection test we don't want to run it a second time
1116
  $connection_test = $this->get_option( 'connection_test' );
1117
+ if ( ! empty( $connection_test ) )
1118
  return true;
1119
 
1120
  // force update firewall settings
1121
  $this->update_firewall();
1122
 
1123
+ // Generate a random string for ping-backs to use for identification
1124
+ $connection_test_key = wp_generate_password( 32, false );
1125
+ $this->update_option( 'connection_test', $connection_test_key );
1126
+
1127
  // initial connection test to server
 
1128
  $this->delete_option( 'allow_forwarded_for' );
1129
  $host = ( ! empty( $_SERVER['HTTP_HOST'] ) ) ? $_SERVER['HTTP_HOST'] : parse_url( $this->site_url(), PHP_URL_HOST );
1130
  $connect = $this->contact_service( 'test', array( 'host' => $host, 'uri' => $_SERVER['REQUEST_URI'], 'ssl' => is_ssl() ) );
1156
  }
1157
 
1158
  // test connection between the site and the servers
1159
+ $connect = (string)$this->contact_service( 'test', array( 'type' => 'connect', 'test_key' => $connection_test_key ) );
1160
  if ( 'ok' != $connect ) {
1161
+ if ( 'error' == $connect ) {
1162
+ $this->update_option( 'connection_error_code', -1 );
1163
+ $this->update_option( 'connection_error_message', sprintf( __( 'The VaultPress servers cannot connect to your site. Please check that your site is visible over the Internet and there are no firewall or load balancer settings on your server that might be blocking the communication. If you&rsquo;re still having issues please <a href="%1$s">contact the VaultPress&nbsp;Safekeepers</a>.', 'vaultpress' ), 'http://vaultpress.com/contact/' ) );
1164
+ } elseif ( !empty( $connect['faultCode'] ) ) {
1165
+ $this->update_option( 'connection_error_code', $connect['faultCode'] );
1166
+ $this->update_option( 'connection_error_message', $connect['faultString'] );
 
 
 
 
 
 
 
 
 
 
 
1167
  }
1168
+
1169
+ $this->update_option( 'connection', time() );
1170
+ $this->delete_option( 'connection_test' );
1171
+ return false;
1172
  }
1173
 
1174
  // successful connection established
1933
  }
1934
 
1935
  // Figure out possible remote IPs
1936
+ $remote_ips = array();
 
 
1937
  if ( !empty( $_SERVER['REMOTE_ADDR'] ) )
1938
+ $remote_ips['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
1939
+
1940
+ // If this is a pingback during a connection test, search for valid-looking ips among headers
1941
+ $connection_test_key = $this->get_option( 'connection_test' );
1942
+ $testing_all_headers = ( ! empty( $_POST['test_key'] ) && $_POST['test_key'] === $connection_test_key );
1943
+ if ( $testing_all_headers ) {
1944
+ $remote_ips = array_filter( $_SERVER, array( $this, 'looks_like_ip_list' ) );
1945
+ }
1946
+
1947
+ // If there is a pre-configured forwarding IP header, check that.
1948
+ $forward_header = $this->get_option( 'allow_forwarded_for' );
1949
+ if ( true === $forward_header || 1 == $forward_header ) {
1950
+ $forward_header = 'HTTP_X_FORWARDED_FOR';
1951
+ }
1952
+ if ( ! empty( $forward_header ) && ! empty( $_SERVER[ $forward_header ] ) ) {
1953
+ $remote_ips[ $forward_header ] = $_SERVER[ $forward_header ];
1954
+ }
1955
 
1956
  if ( empty( $remote_ips ) ) {
1957
  $__vp_validate_error = array( 'error' => 'no_remote_addr', 'detail' => (int) $this->get_option( 'allow_forwarded_for' ) ); // shouldn't happen
1958
  return false;
1959
  }
1960
+
1961
+ foreach ( $remote_ips as $header_name => $ip_list ) {
1962
+ $ips = explode( ',', $ip_list );
1963
+ foreach ( $ips as $ip ) {
1964
+ $ip = preg_replace( '#^::(ffff:)?#', '', $ip );
1965
+ if ( $cidr = $this->ip_in_cidrs( $ip, $cidrs ) ) {
1966
+ // Successful match found. If testing all headers, note the successful header.
1967
+ if ( $testing_all_headers && 'REMOTE_ADDR' !== $header_name ) {
1968
+ $this->update_option( 'allow_forwarded_for', $header_name );
1969
+ }
1970
+
1971
+ return true;
1972
+ }
1973
  }
1974
  }
1975
 
1976
  $__vp_validate_error = array( 'error' => 'remote_addr_fail', 'detail' => $remote_ips );
1977
  return false;
1978
  }
1979
+
1980
+ // Returns true if $value looks like a comma-separated list of IPs
1981
+ function looks_like_ip_list( $value ) {
1982
+ if ( ! is_string( $value ) ) {
1983
+ return false;
1984
+ }
1985
+
1986
+ $items = explode( ',', $value );
1987
+ foreach ( $items as $item ) {
1988
+ if ( ip2long( $item ) === false ) {
1989
+ return false;
1990
+ }
1991
+ }
1992
+
1993
+ return true;
1994
+ }
1995
 
1996
  function do_c_block_firewall() {
1997
  // Perform the firewall check by class-c ip blocks