PluginProbe
The WP Remote WordPress Plugin / 6.47
The WP Remote WordPress Plugin v6.47
6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 5.73 All 53 releases
wpremote / helper.php

helper.php in The WP Remote WordPress Plugin 6.47, at helper.php

353 lines 10.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH') && !defined('MCDATAPATH') && !defined('PHP_ERR_MONIT_PATH')) exit;
3
4 if (!class_exists('WPRHelper')) :
5 class WPRHelper {
6 public static function safePregMatch($pattern, $subject, &$matches = null, $flags = 0, $offset = 0) {
7 if (!is_string($pattern) || !is_string($subject)) {
8 return false;
9 }
10 return preg_match($pattern, $subject, $matches, $flags, $offset);
11 }
12
13 # XNOTE - The below function assumes valid input
14 # $array should be an array and $keys should be an array of string, or integer data
15 public static function filterArray($array, $keys) {
16 $filteredArray = array();
17 foreach ($keys as $key) {
18 if (array_key_exists($key, $array)) {
19 $filteredArray[$key] = $array[$key];
20 }
21 }
22 return $filteredArray;
23 }
24
25 # XNOTE - The below function assumes valid input
26 # $array should be an array and $keys should be an array of string, or integer data
27 public static function digArray($array, $keys) {
28 if (empty($keys)) {
29 return null;
30 }
31 $curr_array = $array;
32 foreach ($keys as $key) {
33 if (is_array($curr_array) && array_key_exists($key, $curr_array)) {
34 $curr_array = $curr_array[$key];
35 } else {
36 return null;
37 }
38 }
39 return $curr_array;
40 }
41
42 public static function arrayKeyFirst($array) {
43 if (!function_exists('array_key_first')) {
44 foreach ($array as $key => $value) {
45 return $key;
46 }
47 return null;
48 }
49
50 return array_key_first($array);
51 }
52
53 public static function safePregReplace($replace_regex, $replace_string, $element, $limit = -1) {
54 if (!is_string($replace_regex) || !is_string($replace_string) || !is_string($element) || !is_int($limit)) {
55 return $element;
56 }
57
58 $updated_element = preg_replace($replace_regex, $replace_string, $element, $limit);
59
60 if ($updated_element === null && preg_last_error() !== PREG_NO_ERROR) {
61 return $element;
62 }
63
64 return $updated_element;
65 }
66
67 public static function safeStrReplace($search, $replace, $subject) {
68 if (!is_string($search) || !is_string($replace) || !is_string($subject)) {
69 return $subject;
70 }
71 $updated_subject = str_replace($search, $replace, $subject);
72 if ($updated_subject === null) {
73 return $subject;
74 }
75 return $updated_subject;
76 }
77
78 public static function preInitWPHook($hook_name, $function_name, $priority, $accepted_args) {
79 global $wp_filter;
80
81 // Check if $wp_filter is not initialized or not an array
82 if (!isset($wp_filter) || !is_array($wp_filter)) {
83 $wp_filter = array();
84 }
85
86 // Check if the hook exists in $wp_filter
87 if (!isset($wp_filter[$hook_name])) {
88 $wp_filter[$hook_name] = array();
89 }
90
91 // Check if the priority exists for the hook
92 if (!isset($wp_filter[$hook_name][$priority])) {
93 $wp_filter[$hook_name][$priority] = array();
94 }
95
96 // Add the filter function information to the $wp_filter array
97 $wp_filter[$hook_name][$priority][] = array(
98 'function' => $function_name,
99 'accepted_args' => $accepted_args,
100 );
101 }
102
103 public static function removePatternFromWpConfig($pattern) {
104 if (!defined('ABSPATH')) {
105 return;
106 }
107
108 $wp_conf_paths = array(
109 rtrim(ABSPATH, DIRECTORY_SEPARATOR) . "/wp-config.php",
110 rtrim(ABSPATH, DIRECTORY_SEPARATOR) . "../wp-config.php"
111 );
112
113 if (file_exists($wp_conf_paths[0])) {
114 $fname = $wp_conf_paths[0];
115 } elseif (file_exists($wp_conf_paths[1])) {
116 $fname = $wp_conf_paths[1];
117 } else {
118 return;
119 }
120
121 self::fileRemovePattern($fname, $pattern);
122 }
123
124 public static function fileRemovePattern($fname, $pattern, $is_regex = false) {
125 if (!is_string($fname) || !is_string($pattern)) {
126 return;
127 }
128
129 if (!WPRWPFileSystem::getInstance()->exists($fname)) {
130 return;
131 }
132
133 $content = WPRWPFileSystem::getInstance()->getContents($fname);
134 if ($content !== false) {
135 if ($is_regex !== false) {
136 $modified_content = preg_replace($pattern, "", $content);
137 } else {
138 $modified_content = str_replace($pattern, "", $content);
139 }
140
141 if (empty($modified_content)) {
142 return;
143 }
144
145 if ($content !== $modified_content) {
146 WPRWPFileSystem::getInstance()->putContents($fname, $modified_content,
147 WPRWPFileSystem::getInstance()->getchmodOctal($fname));
148 }
149 }
150 }
151
152 public static function opensslEncrypt($plain_text, $cipher_algo, $encryption_key, $iv = null) {
153 if (!function_exists('openssl_encrypt') || !function_exists('openssl_get_cipher_methods') ||
154 !function_exists('openssl_random_pseudo_bytes') || !function_exists('openssl_cipher_iv_length')) {
155 return array(false, "OpenSSL extension not found.");
156 }
157
158 if (empty($plain_text) || !is_string($plain_text) ||
159 empty($encryption_key) || !is_string($encryption_key)) {
160 return array(false, "Plain text or encryption key is not a valid string.");
161 }
162
163 if (!in_array($cipher_algo, openssl_get_cipher_methods(), true)) {
164 return array(false, "Invalid cipher algorithm - " . $cipher_algo);
165 }
166
167 if ($iv === null) {
168 $iv_length = openssl_cipher_iv_length($cipher_algo);
169 if ($iv_length === false) {
170 return array(false, "IV length not found.");
171 }
172 $iv = openssl_random_pseudo_bytes($iv_length);
173 if ($iv === false) {
174 return array(false, "IV generation failed.");
175 }
176 }
177
178 if (strlen($iv) !== $iv_length) {
179 return array(false, "Invalid IV length. Expected length is " . $iv_length . " bytes.");
180 }
181
182 $encrypted_data = openssl_encrypt($plain_text, $cipher_algo, $encryption_key, OPENSSL_RAW_DATA, $iv);
183 if ($encrypted_data === false) {
184 return array(false, "Encryption failed.");
185 }
186
187 return array(true, ($iv . $encrypted_data));
188 }
189
190 public static function opensslDecrypt($data, $cipher_algo, $encryption_key) {
191 if (!function_exists('openssl_decrypt') || !function_exists('openssl_get_cipher_methods') ||
192 !function_exists('openssl_cipher_iv_length')) {
193 return array(false, "OpenSSL extension not found.");
194 }
195
196 if (empty($data) || !is_string($data) || empty($encryption_key) || !is_string($encryption_key)) {
197 return array(false, "Encrypted secret or encryption key is not a valid string.");
198 }
199
200 if (!in_array($cipher_algo, openssl_get_cipher_methods(), true)) {
201 return array(false, "Invalid cipher algorithm - " . $cipher_algo);
202 }
203
204 $iv_length = openssl_cipher_iv_length($cipher_algo);
205 if ($iv_length === false) {
206 return array(false, "IV length not found.");
207 }
208
209 if (strlen($data) <= $iv_length) {
210 return array(false, "Data length is insufficient to contain IV.");
211 }
212
213 $iv = substr($data, 0, $iv_length);
214 $encrypted_data = substr($data, $iv_length);
215
216 if ($iv === false || $encrypted_data === false) {
217 return array(false, "IV or encrypted data not found.");
218 }
219
220 $decrypted_data = openssl_decrypt($encrypted_data, $cipher_algo, $encryption_key, OPENSSL_RAW_DATA, $iv);
221
222 if ($decrypted_data === false) {
223 return array(false, "Decryption failed.");
224 }
225
226 return array(true, $decrypted_data);
227 }
228
229 public static function get_direct_filesystem() {
230 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
231 require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
232 return new WP_Filesystem_Direct(new StdClass());
233 }
234
235 /**
236 * Maybe unslash a value if WordPress is loaded
237 *
238 * @param string $value The value to potentially unslash
239 * @return string The unslashed value if WP is loaded, original value otherwise
240 */
241 public static function maybeUnslashValue($value) {
242 if (function_exists('wp_unslash')) {
243 return wp_unslash($value);
244 }
245 return $value;
246 }
247
248 /**
249 * Get and sanitize a string parameter from superglobal
250 *
251 * @param string $superglobal The superglobal type ('GET', 'POST', etc.)
252 * @param string $key The parameter key to retrieve
253 * @param string $context The sanitization context ('text', 'email', 'url')
254 * @return string|null Sanitized string value or null if invalid or unknown context
255 */
256 public static function getStringParamSanitized($superglobal, $key, $context) {
257 $raw_value = self::getRawParam($superglobal, $key);
258
259 if (!is_string($raw_value)) {
260 return null;
261 }
262
263 switch ($context) {
264 case 'text':
265 if (!function_exists('sanitize_text_field')) {
266 return null;
267 }
268 return sanitize_text_field($raw_value);
269 case 'email':
270 if (!function_exists('sanitize_email')) {
271 return null;
272 }
273 return sanitize_email($raw_value);
274 case 'url':
275 if (!function_exists('esc_url_raw')) {
276 return null;
277 }
278 return esc_url_raw($raw_value);
279 default:
280 return null;
281 }
282 }
283
284 /**
285 * Get and escape a string parameter from superglobal
286 *
287 * @param string $superglobal The superglobal type ('GET', 'POST', etc.)
288 * @param string $key The parameter key to retrieve
289 * @param string $context The escaping context ('attr', 'html', 'url')
290 * @return string|null Escaped string value or null if invalid or unknown context
291 */
292 public static function getStringParamEscaped($superglobal, $key, $context) {
293 $raw_value = self::getRawParam($superglobal, $key);
294
295 if (!is_string($raw_value)) {
296 return null;
297 }
298
299 switch ($context) {
300 case 'attr':
301 if (!function_exists('esc_attr')) {
302 return null;
303 }
304 return esc_attr($raw_value);
305 case 'html':
306 if (!function_exists('esc_html')) {
307 return null;
308 }
309 return esc_html($raw_value);
310 case 'url':
311 if (!function_exists('esc_url')) {
312 return null;
313 }
314 return esc_url($raw_value);
315 default:
316 return null;
317 }
318 }
319
320 // phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
321 /**
322 * Get raw parameter value from superglobal
323 *
324 * @param string $superglobal The superglobal type ('GET', 'POST', etc.)
325 * @param string $key The parameter key to retrieve
326 * @return mixed Raw parameter value or null if not found
327 */
328 public static function getRawParam($superglobal, $key) {
329 $value = null;
330
331 switch (strtoupper($superglobal)) {
332 case 'GET':
333 $value = isset($_GET[$key]) ? $_GET[$key] : null;
334 break;
335 case 'POST':
336 $value = isset($_POST[$key]) ? $_POST[$key] : null;
337 break;
338 case 'COOKIE':
339 $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : null;
340 break;
341 case 'REQUEST':
342 $value = isset($_REQUEST[$key]) ? $_REQUEST[$key] : null;
343 break;
344 case 'SERVER':
345 $value = isset($_SERVER[$key]) ? $_SERVER[$key] : null;
346 break;
347 }
348
349 return $value !== null ? self::maybeUnslashValue($value) : null;
350 }
351 // phpcs:enable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
352 }
353 endif;