PluginProbe
Patchstack – WordPress & Plugins Security / 2.1.21
Patchstack – WordPress & Plugins Security v2.1.21
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
patchstack / includes / core.php

core.php in Patchstack – WordPress & Plugins Security 2.1.21, at includes/core.php

263 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Do not allow the file to be called directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * The core class is used as a base class for all the other classes.
10 * This will allow us to declare certain global methods/variables.
11 */
12 class P_Core {
13
14 /**
15 * This will allow us to communicate between classes.
16 *
17 * @var Patchstack
18 */
19 public $plugin;
20
21 /**
22 * Whether or not the site is a multisite.
23 *
24 * @var boolean
25 */
26 private $is_multi_site = false;
27
28 /**
29 * Allowed HTML for the wp_kses function used to render certain paragraphs of texts.
30 *
31 * @var array
32 */
33 public $allowed_html = array(
34 'a' => array(
35 'href' => array(),
36 'title' => array(),
37 'target' => array()
38 ),
39 'p' => array(
40 'style' => array()
41 ),
42 'span' => array(
43 'style' => array()
44 ),
45 'br' => array(),
46 'strong' => array(),
47 'b' => array(),
48 'i' => array(
49 'style' => array()
50 ),
51 'label' => array(
52 'for' => array(),
53 'style' => array()
54 ),
55 'input' => array(
56 'type' => array(),
57 'class' => array(),
58 'name' => array(),
59 'id' => array(),
60 'value' => array(),
61 'checked' => array(),
62 'style' => array()
63 ),
64 'textarea' => array(
65 'rows' => array(),
66 'id' => array(),
67 'name' => array()
68 ),
69 'select' => array(
70 'name' => array(),
71 'id' => array(),
72 'data-selected' => array()
73 ),
74 'option' => array(
75 'value' => array(),
76 'selected' => array()
77 ),
78 'table' => array(
79 'class' => array(),
80 'style' => array()
81 ),
82 'thead' => array(),
83 'th' => array(
84 'style' => array()
85 ),
86 'tr' => array(),
87 'td' => array(),
88 'div' => array(
89 'class' => array(),
90 'style' => array()
91 )
92 );
93
94 /**
95 * Some of the IP addresses of Patchstack.
96 *
97 * @var array
98 */
99 public $ips = array(
100 '18.221.197.243',
101 '52.15.237.250',
102 '3.19.3.34',
103 '3.18.238.17',
104 '13.58.49.77',
105 '18.222.191.77',
106 '3.131.108.250',
107 '3.23.157.140',
108 '18.220.70.233',
109 '3.140.84.221',
110 '185.212.171.100'
111 );
112
113 /**
114 * @param Patchstack $plugin
115 * @return void
116 */
117 public function __construct( $plugin ) {
118 $this->plugin = $plugin;
119 $this->is_multi_site = is_multisite();
120 }
121
122 /**
123 * In case of multisite we want to determine if there's a difference between the
124 * network setting and site setting and if so, use the site setting.
125 *
126 * @param string $name
127 * @param mixed $default
128 * @return mixed
129 */
130 public function get_option( $name, $default = false ) {
131 // We always want to return the site option on the default settings management page.
132 if ( isset( $_GET['page'] ) && $_GET['page'] == 'patchstack-multisite-settings' && is_super_admin() ) {
133 return get_site_option( $name, $default );
134 }
135
136 // Get the setting of the current site.
137 $secondary = get_option( $name, $default );
138
139 // Get the setting of the network and in case there's a difference,
140 // return the value of site.
141 $main = get_site_option( $name, $default );
142 return $main != $secondary ? $secondary : $main;
143 }
144
145 /**
146 * In case we need to retrieve the option of a specific site, we can use this.
147 * It will determine if it's on a multisite environment and if so, use get_blog_option.
148 *
149 * @param int $site_id
150 * @param string $name
151 * @param mixed $default
152 * @return mixed
153 */
154 public function get_blog_option( $site_id, $name, $default = false ) {
155 if ( $this->is_multi_site ) {
156 return get_blog_option( $site_id, $name, $default );
157 }
158
159 return get_option( $name, $default );
160 }
161
162 /**
163 * In case we need to update the option of a specific site, we can use this.
164 * It will determine if it's on a multisite environment and if so, use update_blog_option.
165 *
166 * @param int $site_id
167 * @param string $name
168 * @param mixed $value
169 * @return mixed
170 */
171 public function update_blog_option( $site_id, $name, $value ) {
172 if ( $this->is_multi_site ) {
173 return update_blog_option( $site_id, $name, $value );
174 }
175
176 return update_option( $name, $value );
177 }
178
179 /**
180 * Determine if the license is active and not expired.
181 *
182 * @return boolean
183 */
184 public function license_is_active() {
185 if ( get_option( 'patchstack_license_activated', 0 ) ) {
186 return true;
187 }
188
189 $expiry = get_option( 'patchstack_license_expiry', '' );
190 if ( $expiry != '' && ( strtotime( $expiry ) < ( time() + ( 3600 * 24 ) ) ) ) {
191 return true;
192 }
193
194 return false;
195 }
196
197 /**
198 * Determine if a given PHP function is disabled or not.
199 *
200 * @param string $name Name of the function to check.
201 * @return boolean Whether or not the function is available to call.
202 */
203 public function function_available( $name ) {
204 $safe_mode = ini_get( 'safe_mode' );
205 if ( $safe_mode && strtolower( $safe_mode ) != 'off' ) {
206 return false;
207 }
208
209 // Determine if the function is available.
210 if ( in_array( $name, array_map( 'trim', explode( ',', ini_get( 'disable_functions' ) ) ) ) ) {
211 return false;
212 }
213
214 return true;
215 }
216
217 /**
218 * Attempt to get the client IP by checking all possible IP (proxy) headers.
219 *
220 * @return string
221 */
222 public function get_ip() {
223 // IP address header override set?
224 $override = get_site_option( 'patchstack_firewall_ip_header', '' );
225 if ( $override != '' && isset( $_SERVER[ $override ] ) ) {
226 return $_SERVER[ $override ];
227 }
228
229 // IP address headers which should have priority and be used regardless of other headers.
230 $priority = array( 'HTTP_CF_CONNECTING_IP', 'HTTP_X_SUCURI_CLIENTIP' );
231 foreach ( $priority as $header ) {
232 if ( isset( $_SERVER[ $header ] ) && filter_var( $_SERVER[ $header ], FILTER_VALIDATE_IP ) !== false ) {
233 return $_SERVER[ $header ];
234 }
235 }
236
237 // Special case for hosts that have a weird configuration.
238 if ( $this->function_available( 'php_uname' ) ) {
239 $uname = @php_uname();
240
241 // Bluehos and Hostmonster store the real IP in $_SERVER['REMOTE_ADDR'] but the proxy IP in HTTP_X_FORWARDED_FOR.t
242 if ( strpos( $uname, 'bluehost' ) !== false || strpos( $uname, 'hostmonster' ) !== false ) {
243 return $_SERVER['REMOTE_ADDR'];
244 }
245
246 // Hostgator stores the real IP in $_SERVER['REMOTE_ADDR'] but the proxy IP in HTTP_X_FORWARDED_FOR.
247 if ( ( strpos( $uname, 'websitewelcome' ) || strpos( $uname, 'hostgator' ) ) && isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) && $_SERVER['HTTP_X_FORWARDED_FOR'] != $_SERVER['REMOTE_ADDR'] ) {
248 return $_SERVER['REMOTE_ADDR'];
249 }
250 }
251
252 // In order of priority, try to get the IP address.
253 $allowed = array( 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'SUCURI_RIP', 'REMOTE_ADDR' );
254 foreach ( $allowed as $header ) {
255 if ( isset( $_SERVER[ $header ] ) && filter_var( $_SERVER[ $header ], FILTER_VALIDATE_IP ) !== false ) {
256 return $_SERVER[ $header ];
257 }
258 }
259
260 return '127.0.0.1';
261 }
262 }
263