PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.1-beta.3
Jetpack – WP Security, Backup, Speed, & Growth v16.1-beta.3
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-connection / src / class-authorize-json-api.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src Last commit date
abilities 2 months ago connectors 1 month ago health 1 month ago identity-crisis 1 month ago sso 1 month ago traits 9 months ago webhooks 9 months ago class-authorize-json-api.php 1 month ago class-client.php 8 months ago class-connection-assets.php 1 year ago class-connection-notice.php 8 months ago class-error-handler.php 2 weeks ago class-external-storage.php 4 months ago class-heartbeat.php 1 month ago class-initial-state.php 4 weeks ago class-manager.php 2 weeks ago class-nonce-handler.php 9 months ago class-package-version-tracker.php 1 month ago class-package-version.php 2 weeks ago class-partner-coupon.php 2 months ago class-partner.php 2 years ago class-plugin-storage.php 8 months ago class-plugin.php 9 months ago class-rest-authentication.php 9 months ago class-rest-connector.php 4 weeks ago class-secrets.php 9 months ago class-server-sandbox.php 2 months ago class-site-health.php 2 months ago class-terms-of-service.php 2 years ago class-tokens-locks.php 9 months ago class-tokens.php 9 months ago class-tracking.php 2 months ago class-urls.php 6 months ago class-user-account-status.php 9 months ago class-users-connection-admin.php 2 months ago class-utils.php 2 years ago class-webhooks.php 1 month ago class-xmlrpc-async-call.php 2 years ago class-xmlrpc-connector.php 9 months ago interface-manager.php 4 years ago interface-storage-provider.php 6 months ago
class-authorize-json-api.php
282 lines
1 <?php
2 /**
3 * Authorize_Json_Api handler class.
4 * Used to handle connections via JSON API.
5 * Ported from the Jetpack class.
6 *
7 * @since 2.7.6 Ported from the Jetpack class.
8 *
9 * @package automattic/jetpack-connection
10 */
11
12 namespace Automattic\Jetpack\Connection;
13
14 use Automattic\Jetpack\Redirect;
15 use Automattic\Jetpack\Status\Host;
16 use Jetpack_Options;
17
18 /**
19 * Authorize_Json_Api handler class.
20 */
21 class Authorize_Json_Api {
22 /**
23 * Verified data for JSON authorization request
24 *
25 * @since 2.7.6
26 *
27 * @var array
28 */
29 public $json_api_authorization_request = array();
30
31 /**
32 * Verifies the request by checking the signature
33 *
34 * @since jetpack-4.6.0 Method was updated to use `$_REQUEST` instead of `$_GET` and `$_POST`. Method also updated to allow
35 * passing in an `$environment` argument that overrides `$_REQUEST`. This was useful for integrating with SSO.
36 * @since 2.7.6 Ported from Jetpack to the Connection package.
37 *
38 * @param null|array $environment Value to override $_REQUEST.
39 *
40 * @return void
41 */
42 public function verify_json_api_authorization_request( $environment = null ) {
43 $environment = $environment === null
44 ? $_REQUEST // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verification handled later in function and request data are 1) used to verify a cryptographic signature of the request data and 2) sanitized later in function.
45 : $environment;
46
47 if ( ! isset( $environment['token'] ) ) {
48 wp_die( esc_html__( 'You must connect your Jetpack plugin to WordPress.com to use this feature.', 'jetpack-connection' ) );
49 }
50
51 list( $env_token,, $env_user_id ) = explode( ':', $environment['token'] );
52 $token = ( new Tokens() )->get_access_token( (int) $env_user_id, $env_token );
53 if ( ! $token || empty( $token->secret ) ) {
54 wp_die( esc_html__( 'You must connect your Jetpack plugin to WordPress.com to use this feature.', 'jetpack-connection' ) );
55 }
56
57 $die_error = __( 'Someone may be trying to trick you into giving them access to your site. Or it could be you just encountered a bug :). Either way, please close this window.', 'jetpack-connection' );
58
59 // Host has encoded the request URL, probably as a result of a bad http => https redirect.
60 if (
61 preg_match( '/https?%3A%2F%2F/i', esc_url_raw( wp_unslash( $_GET['redirect_to'] ) ) ) > 0 // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated -- no site changes, we're erroring out.
62 ) {
63 /**
64 * Jetpack authorisation request Error.
65 *
66 * @since jetpack-7.5.0
67 */
68 do_action( 'jetpack_verify_api_authorization_request_error_double_encode' );
69 $die_error = sprintf(
70 /* translators: %s is a URL */
71 __( 'Your site is incorrectly double-encoding redirects from http to https. This is preventing Jetpack from authenticating your connection. Please visit our <a href="%s">support page</a> for details about how to resolve this.', 'jetpack-connection' ),
72 esc_url( Redirect::get_url( 'jetpack-support-double-encoding' ) )
73 );
74 }
75
76 $jetpack_signature = new \Jetpack_Signature( $token->secret, (int) Jetpack_Options::get_option( 'time_diff' ) );
77
78 if ( isset( $environment['jetpack_json_api_original_query'] ) ) {
79 $signature = $jetpack_signature->sign_request(
80 $environment['token'],
81 $environment['timestamp'],
82 $environment['nonce'],
83 '',
84 'GET',
85 $environment['jetpack_json_api_original_query'],
86 null,
87 true
88 );
89 } else {
90 $signature = $jetpack_signature->sign_current_request(
91 array(
92 'body' => null,
93 'method' => 'GET',
94 )
95 );
96 }
97
98 if ( ! $signature ) {
99 wp_die(
100 wp_kses(
101 $die_error,
102 array(
103 'a' => array(
104 'href' => array(),
105 ),
106 )
107 )
108 );
109 } elseif ( is_wp_error( $signature ) ) {
110 wp_die(
111 wp_kses(
112 $die_error,
113 array(
114 'a' => array(
115 'href' => array(),
116 ),
117 )
118 )
119 );
120 } elseif ( ! hash_equals( $signature, $environment['signature'] ) ) {
121 if ( is_ssl() ) {
122 // If we signed an HTTP request on the Jetpack Servers, but got redirected to HTTPS by the local blog, check the HTTP signature as well.
123 $signature = $jetpack_signature->sign_current_request(
124 array(
125 'scheme' => 'http',
126 'body' => null,
127 'method' => 'GET',
128 )
129 );
130 if ( ! $signature || is_wp_error( $signature ) || ! hash_equals( $signature, $environment['signature'] ) ) {
131 wp_die(
132 wp_kses(
133 $die_error,
134 array(
135 'a' => array(
136 'href' => array(),
137 ),
138 )
139 )
140 );
141 }
142 } else {
143 wp_die(
144 wp_kses(
145 $die_error,
146 array(
147 'a' => array(
148 'href' => array(),
149 ),
150 )
151 )
152 );
153 }
154 }
155
156 $timestamp = (int) $environment['timestamp'];
157 $nonce = stripslashes( (string) $environment['nonce'] );
158
159 if ( ! ( new Nonce_Handler() )->add( $timestamp, $nonce ) ) {
160 // De-nonce the nonce, at least for 5 minutes.
161 // We have to reuse this nonce at least once (used the first time when the initial request is made, used a second time when the login form is POSTed).
162 $old_nonce_time = get_option( "jetpack_nonce_{$timestamp}_{$nonce}" );
163 if ( $old_nonce_time < time() - 300 ) {
164 wp_die( esc_html__( 'The authorization process expired. Please go back and try again.', 'jetpack-connection' ) );
165 }
166 }
167
168 $data = json_decode(
169 base64_decode( stripslashes( $environment['data'] ) ) // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode
170 );
171 $data_filters = array(
172 'state' => 'opaque',
173 'client_id' => 'int',
174 'client_title' => 'string',
175 'client_image' => 'url',
176 );
177
178 foreach ( $data_filters as $key => $sanitation ) {
179 if ( ! isset( $data->$key ) ) {
180 wp_die(
181 wp_kses(
182 $die_error,
183 array(
184 'a' => array(
185 'href' => array(),
186 ),
187 )
188 )
189 );
190 }
191
192 switch ( $sanitation ) {
193 case 'int':
194 $this->json_api_authorization_request[ $key ] = (int) $data->$key;
195 break;
196 case 'opaque':
197 $this->json_api_authorization_request[ $key ] = (string) $data->$key;
198 break;
199 case 'string':
200 $this->json_api_authorization_request[ $key ] = wp_kses( (string) $data->$key, array() );
201 break;
202 case 'url':
203 $this->json_api_authorization_request[ $key ] = esc_url_raw( (string) $data->$key );
204 break;
205 }
206 }
207
208 if ( empty( $this->json_api_authorization_request['client_id'] ) ) {
209 wp_die(
210 wp_kses(
211 $die_error,
212 array(
213 'a' => array(
214 'href' => array(),
215 ),
216 )
217 )
218 );
219 }
220 }
221
222 /**
223 * Add the Access Code details to the public-api.wordpress.com redirect.
224 *
225 * @since 2.7.6 Ported from Jetpack to the Connection package.
226 *
227 * @param string $redirect_to URL.
228 * @param string $original_redirect_to URL.
229 * @param \WP_User $user WP_User for the redirect.
230 *
231 * @return string
232 */
233 public function add_token_to_login_redirect_json_api_authorization( $redirect_to, $original_redirect_to, $user ) {
234 return add_query_arg(
235 urlencode_deep(
236 array(
237 'jetpack-code' => get_user_meta(
238 $user->ID,
239 'jetpack_json_api_' . $this->json_api_authorization_request['client_id'],
240 true
241 ),
242 'jetpack-user-id' => (int) $user->ID,
243 'jetpack-state' => $this->json_api_authorization_request['state'],
244 )
245 ),
246 $redirect_to
247 );
248 }
249
250 /**
251 * If someone logs in to approve API access, store the Access Code in usermeta.
252 *
253 * @since 2.7.6 Ported from Jetpack to the Connection package.
254 *
255 * @param string $user_login Unused.
256 * @param \WP_User $user User logged in.
257 *
258 * @return void
259 */
260 public function store_json_api_authorization_token( $user_login, $user ) {
261 add_filter( 'login_redirect', array( $this, 'add_token_to_login_redirect_json_api_authorization' ), 10, 3 );
262 add_filter( 'allowed_redirect_hosts', array( Host::class, 'allow_wpcom_public_api_domain' ) );
263 $token = wp_generate_password( 32, false );
264 update_user_meta( $user->ID, 'jetpack_json_api_' . $this->json_api_authorization_request['client_id'], $token );
265 }
266
267 /**
268 * HTML for the JSON API authorization notice.
269 *
270 * @since 2.7.6 Ported from Jetpack to the Connection package.
271 *
272 * @return string
273 */
274 public function login_message_json_api_authorization() {
275 return '<p class="message">' . sprintf(
276 /* translators: Name/image of the client requesting authorization */
277 esc_html__( '%s wants to access your site’s data. Log in to authorize that access.', 'jetpack-connection' ),
278 '<strong>' . esc_html( $this->json_api_authorization_request['client_title'] ) . '</strong>'
279 ) . '<img src="' . esc_url( $this->json_api_authorization_request['client_image'] ) . '" /></p>';
280 }
281 }
282