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 / callback / request.php

request.php in The WP Remote WordPress Plugin 6.47, at callback/request.php

314 lines 9.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) exit;
4 if (!class_exists('WPRCallbackRequest')) :
5 class WPRCallbackRequest {
6 public $params;
7 public $method;
8 public $wing;
9 public $is_afterload;
10 public $is_admin_ajax;
11 public $is_debug;
12 public $account;
13 public $settings;
14 public $sig;
15 public $sighshalgo;
16 public $time;
17 public $version;
18 public $is_sha1;
19 public $bvb64stream;
20 public $bvb64cksize;
21 public $checksum;
22 public $error = array();
23 public $pubkey_name;
24 public $bvprmsmac;
25 public $bvboundry;
26
27 private static $SIG_HASH_ALGO_MAP = array(
28 '1' => OPENSSL_ALGO_SHA1,
29 '7' => OPENSSL_ALGO_SHA256
30 );
31
32 public function __construct($account, $in_params, $settings) {
33 $this->params = array();
34 $this->account = $account;
35 $this->settings = $settings;
36 $this->wing = $in_params['wing'];
37 $this->method = $in_params['bvMethod'];
38 $this->is_afterload = array_key_exists('afterload', $in_params);
39 $this->is_admin_ajax = array_key_exists('adajx', $in_params);
40 $this->is_debug = array_key_exists('bvdbg', $in_params);
41 $this->sig = $in_params['sig'];
42 $this->sighshalgo = !empty($in_params['sighshalgo']) ? $in_params['sighshalgo'] : '1';
43 $this->time = intval($in_params['bvTime']);
44 $this->version = $in_params['bvVersion'];
45 $this->is_sha1 = array_key_exists('sha1', $in_params);
46 $this->bvb64stream = isset($in_params['bvb64stream']);
47 $this->bvb64cksize = array_key_exists('bvb64cksize', $in_params) ? intval($in_params['bvb64cksize']) : false;
48 $this->checksum = array_key_exists('checksum', $in_params) ? $in_params['checksum'] : false;
49 $this->pubkey_name = !empty($in_params['pubkeyname']) ?
50 WPRAccount::sanitizeKey($in_params['pubkeyname']) : 'm_public';
51 $this->bvprmsmac = !empty($in_params['bvprmsmac']) ? WPRAccount::sanitizeKey($in_params['bvprmsmac']) : "";
52 $this->bvboundry = !empty($in_params['bvboundry']) ? $in_params['bvboundry'] : "";
53 }
54
55 public function isAPICall() {
56 return array_key_exists('apicall', $this->params);
57 }
58
59 public function http_request($url, $body) {
60 $body = http_build_query($body);
61 $response = wp_remote_post($url, array(
62 'body' => $body,
63 'timeout' => 15,
64 'headers' => array(
65 'Content-Type' => 'application/x-www-form-urlencoded',
66 ),
67 ));
68
69 if (is_wp_error($response)) {
70 return false;
71 }
72
73 return wp_remote_retrieve_body($response);
74 }
75
76 public function get_params_via_api($params_key, $apiurl) {
77 $res = $this->http_request($apiurl, array('bvkey' => $params_key));
78
79 if ($res === FALSE) {
80 return false;
81 }
82
83 return $res;
84 }
85
86 public function info() {
87 $info = array(
88 "requestedsig" => $this->sig,
89 "requestedtime" => $this->time,
90 "requestedversion" => $this->version,
91 "error" => $this->error
92 );
93 if ($this->is_debug) {
94 $info["inreq"] = $this->params;
95 }
96 if ($this->is_admin_ajax) {
97 $info["adajx"] = true;
98 }
99 if ($this->is_afterload) {
100 $info["afterload"] = true;
101 }
102 return $info;
103 }
104
105 public function processParams($in_params) {
106 $params = array();
107
108 if (array_key_exists('obend', $in_params) && function_exists('ob_end_clean'))
109 @ob_end_clean();
110
111 if (array_key_exists('op_reset', $in_params) && function_exists('output_reset_rewrite_vars'))
112 @output_reset_rewrite_vars();
113
114 if (array_key_exists('concat', $in_params)) {
115 foreach ($in_params['concat'] as $key) {
116 $concated = '';
117 $count = intval($in_params[$key]);
118 for ($i = 1; $i <= $count; $i++) {
119 $concated .= $in_params[$key."_bv_".$i];
120 }
121 $in_params[$key] = $concated;
122 }
123 }
124
125 if (isset($in_params['bvpdataviaapi']) && isset($in_params['bvapiurl'])) {
126 $pdata = $this->get_params_via_api($in_params['bvpdataviaapi'], $in_params['bvapiurl']);
127 if ($pdata !== false) {
128 $in_params["bvprms"] = $pdata;
129 }
130 }
131
132 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
133 if (!empty($in_params['bvprmshshalgo']) && $in_params['bvprmshshalgo'] === 'sha256') {
134 $calculated_mac = hash_hmac('SHA256', $in_params['bvprms'], $this->account->secret);
135 } else {
136 $calculated_mac = hash_hmac('SHA1', $in_params['bvprms'], $this->account->secret);
137 }
138
139 if ($this->compare_mac($this->bvprmsmac, $calculated_mac) === true) {
140
141 if (array_key_exists('b64', $in_params)) {
142 foreach ($in_params['b64'] as $key) {
143 if (is_array($in_params[$key])) {
144 $in_params[$key] = array_map('base64_decode', $in_params[$key]);
145 } else {
146 $in_params[$key] = base64_decode($in_params[$key]);
147 }
148 }
149 }
150
151 if (array_key_exists('unser', $in_params)) {
152 foreach ($in_params['unser'] as $key) {
153 $in_params[$key] = json_decode($in_params[$key], TRUE);
154 }
155 }
156
157 if (array_key_exists('sersafe', $in_params)) {
158 $key = $in_params['sersafe'];
159 $in_params[$key] = WPRCallbackRequest::serialization_safe_decode($in_params[$key]);
160 }
161
162 if (array_key_exists('bvprms', $in_params) && isset($in_params['bvprms'])) {
163 $params = $in_params['bvprms'];
164 }
165
166 if (array_key_exists('clacts', $in_params)) {
167 foreach ($in_params['clacts'] as $action) {
168 remove_all_actions($action);
169 }
170 }
171
172 if (array_key_exists('clallacts', $in_params)) {
173 global $wp_filter;
174 foreach ( $wp_filter as $filter => $val ){
175 remove_all_actions($filter);
176 }
177 }
178
179 if (array_key_exists('memset', $in_params)) {
180 $val = intval($in_params['memset']);
181 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for memory limit adjustment
182 @ini_set('memory_limit', $val.'M');
183 }
184
185 return $params;
186 }
187 }
188 return false;
189 }
190
191 private function compare_mac($l_hash, $r_hash) {
192 if (!is_string($l_hash) || !is_string($r_hash)) {
193 return false;
194 }
195
196 if (strlen($l_hash) !== strlen($r_hash)) {
197 return false;
198 }
199
200 if (function_exists('hash_equals')) {
201 return hash_equals($l_hash, $r_hash);
202 } else {
203 return $l_hash === $r_hash;
204 }
205 }
206
207 public static function serialization_safe_decode($data) {
208 if (is_array($data)) {
209 $data = array_map(array('WPRCallbackRequest', 'serialization_safe_decode'), $data);
210 } elseif (is_string($data)) {
211 $data = base64_decode($data);
212 }
213
214 return $data;
215 }
216
217 public function authenticate() {
218 if (!$this->account) {
219 $this->error["message"] = "ACCOUNT_NOT_FOUND";
220 return false;
221 }
222
223 $bv_last_recv_time = $this->settings->getOption('bvLastRecvTime');
224 if ($this->time < intval($bv_last_recv_time) - 300) {
225 return false;
226 }
227
228 $data = $this->method.$this->account->secret.$this->time.$this->version.$this->bvprmsmac;
229 if (!$this->verify($data, base64_decode($this->sig), $this->sighshalgo)) {
230 return false;
231 }
232 $this->settings->updateOption('bvLastRecvTime', $this->time);
233
234 return 1;
235 }
236
237 public function verify($data, $sig, $sighshalgo) {
238 if (!function_exists('openssl_verify') || !function_exists('openssl_pkey_get_public')) {
239 $this->error["message"] = "OPENSSL_FUNCS_NOT_FOUND";
240 return false;
241 }
242
243 $openssl_algo = array_key_exists($sighshalgo, self::$SIG_HASH_ALGO_MAP) ? self::$SIG_HASH_ALGO_MAP[$sighshalgo] : null;
244 if ($openssl_algo === null) {
245 $this->error["message"] = "UNSUPPORTED_HASH_ALGORITHM: " . $sighshalgo;
246 return false;
247 }
248
249 $key_file = dirname( __DIR__ ) . '/public_keys/' . $this->pubkey_name . '.pub';
250 if (!file_exists($key_file)) {
251 $this->error["message"] = "PUBLIC_KEY_NOT_FOUND";
252 return false;
253 }
254
255 $public_key_str = WPRWPFileSystem::getInstance()->getContents($key_file);
256
257 $public_key = openssl_pkey_get_public($public_key_str);
258 if (!$public_key) {
259 $this->error["message"] = "UNABLE_TO_LOAD_PUBLIC_KEY";
260 return false;
261 }
262
263 $verify = openssl_verify($data, $sig, $public_key, $openssl_algo);
264 if ($verify === 1) {
265 return true;
266 } elseif ($verify === 0) {
267 $this->error["message"] = "INCORRECT_SIGNATURE";
268 $this->error["pubkey_sig"] = substr(hash('md5', $public_key_str), 0, 8);
269 } else {
270 $this->error["message"] = "OPENSSL_VERIFY_FAILED";
271 }
272 return false;
273 }
274
275 public function corruptedParamsResp() {
276 $bvinfo = new WPRInfo($this->settings);
277
278 return array(
279 "account_info" => $this->account->info(),
280 "request_info" => $this->info(),
281 "bvinfo" => $bvinfo->info(),
282 "statusmsg" => "BVPRMS_CORRUPTED"
283 );
284 }
285
286 public function authFailedResp() {
287 $api_public_key = WPRAccount::getApiPublicKey($this->settings);
288 $default_secret = WPRRecover::getDefaultSecret($this->settings);
289 $default_account_pubkey = WPRAccount::getDefaultPublicKey();
290 $bvinfo = new WPRInfo($this->settings);
291 $resp = array(
292 "request_info" => $this->info(),
293 "bvinfo" => $bvinfo->info(),
294 "statusmsg" => "FAILED_AUTH",
295 "api_pubkey" => substr($api_public_key, 0, 8),
296 "def_key_status" => WPRRecover::getSecretStatus($this->settings),
297 "def_sigmatch" => substr(hash('sha1', $this->method.$default_secret.$this->time.$this->version), 0, 8)
298 );
299
300 if (is_string($default_account_pubkey) && strlen($default_account_pubkey) >= 32) {
301 $resp["default_account_pubkey"] = substr($default_account_pubkey, 0, 8);
302 }
303
304 if ($this->account) {
305 $resp["account_info"] = $this->account->info();
306 $resp["sigmatch"] = substr(hash('sha1', $this->method.$this->account->secret.$this->time.$this->version), 0, 6);
307 } else {
308 $resp["account_info"] = array("error" => "ACCOUNT_NOT_FOUND");
309 }
310
311 return $resp;
312 }
313 }
314 endif;