PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
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-server-sandbox.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src Last commit date
abilities 3 days ago connectors 3 days ago health 3 days ago identity-crisis 1 month ago sso 1 month ago traits 8 months ago webhooks 8 months ago class-authorize-json-api.php 1 month ago class-client.php 3 days ago class-connection-assets.php 1 year ago class-connection-notice.php 8 months ago class-error-handler.php 3 days ago class-external-storage.php 4 months ago class-heartbeat.php 1 month ago class-initial-state.php 3 weeks ago class-manager.php 3 days ago class-nonce-handler.php 8 months ago class-package-version-tracker.php 1 month ago class-package-version.php 3 days ago class-partner-coupon.php 2 months ago class-partner.php 2 years ago class-plugin-storage.php 8 months ago class-plugin.php 8 months ago class-rest-authentication.php 3 days ago class-rest-connector.php 3 days ago class-secrets.php 8 months ago class-server-sandbox.php 2 months ago class-site-health.php 3 days ago class-terms-of-service.php 3 days ago class-tokens-locks.php 8 months ago class-tokens.php 3 days ago class-tracking.php 3 days ago class-urls.php 6 months ago class-user-account-status.php 3 days 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 8 months ago interface-manager.php 4 years ago interface-storage-provider.php 6 months ago
class-server-sandbox.php
244 lines
1 <?php
2 /**
3 * The Server_Sandbox class.
4 *
5 * This feature is only useful for Automattic developers.
6 * It configures Jetpack to talk to staging/sandbox servers
7 * on WordPress.com instead of production servers.
8 *
9 * @package automattic/jetpack-sandbox
10 */
11
12 namespace Automattic\Jetpack\Connection;
13
14 use Automattic\Jetpack\Constants;
15
16 /**
17 * The Server_Sandbox class.
18 */
19 class Server_Sandbox {
20
21 /**
22 * Sets up the action hooks for the server sandbox.
23 */
24 public function init() {
25 if ( did_action( 'jetpack_server_sandbox_init' ) ) {
26 return;
27 }
28
29 add_action( 'requests-requests.before_request', array( $this, 'server_sandbox' ), 10, 4 );
30 add_action( 'admin_bar_menu', array( $this, 'admin_bar_add_sandbox_item' ), 999 );
31
32 /**
33 * Fires when the server sandbox is initialized. This action is used to ensure that
34 * the server sandbox action hooks are set up only once.
35 *
36 * @since 1.30.7
37 */
38 do_action( 'jetpack_server_sandbox_init' );
39 }
40
41 /**
42 * Returns the new url and host values.
43 *
44 * @param string $sandbox Sandbox domain.
45 * @param string $url URL of request about to be made.
46 * @param array $headers Headers of request about to be made.
47 * @param string $data The body of request about to be made.
48 * @param string $method The method of request about to be made.
49 *
50 * @return array [ 'url' => new URL, 'host' => new Host, 'new_signature => New signature if url was changed ]
51 */
52 public function server_sandbox_request_parameters( $sandbox, $url, $headers, $data = null, $method = 'GET' ) {
53 $host = '';
54 $new_signature = '';
55
56 if ( ! is_string( $sandbox ) || ! is_string( $url ) ) {
57 return array(
58 'url' => $url,
59 'host' => $host,
60 'new_signature' => $new_signature,
61 );
62 }
63
64 $url_host = wp_parse_url( $url, PHP_URL_HOST );
65
66 switch ( $url_host ) {
67 case 'public-api.wordpress.com':
68 case 'jetpack.wordpress.com':
69 case 'jetpack.com':
70 case 'dashboard.wordpress.com':
71 $host = $headers['Host'] ?? $url_host;
72 $original_url = $url;
73 $url = preg_replace(
74 '@^(https?://)' . preg_quote( $url_host, '@' ) . '(?=[/?#].*|$)@',
75 '${1}' . $sandbox,
76 $url,
77 1
78 );
79
80 /**
81 * Whether to add the X Debug query parameter to the request made to the Sandbox
82 *
83 * @since 1.36.0
84 *
85 * @param bool $add_parameter Whether to add the parameter to the request or not. Default is to false.
86 * @param string $url The URL of the request being made.
87 * @param string $host The host of the request being made.
88 */
89 if ( apply_filters( 'jetpack_sandbox_add_profile_parameter', false, $url, $host ) ) {
90 $url = add_query_arg( 'XDEBUG_PROFILE', 1, $url );
91
92 // URL has been modified since the signature was created. We'll need a new one.
93 $original_url = add_query_arg( 'XDEBUG_PROFILE', 1, $original_url );
94 $new_signature = $this->get_new_signature( $original_url, $headers, $data, $method );
95
96 }
97 }
98
99 return compact( 'url', 'host', 'new_signature' );
100 }
101
102 /**
103 * Gets a new signature for the request
104 *
105 * @param string $url The new URL to be signed.
106 * @param array $headers The headers of the request about to be made.
107 * @param string $data The body of request about to be made.
108 * @param string $method The method of the request about to be made.
109 * @return string|null
110 */
111 private function get_new_signature( $url, $headers, $data, $method ) {
112
113 if ( ! empty( $headers['Authorization'] ) ) {
114 $a_headers = $this->extract_authorization_headers( $headers );
115 if ( ! empty( $a_headers ) ) {
116 $token_details = explode( ':', $a_headers['token'] );
117
118 if ( count( $token_details ) === 3 ) {
119 $user_id = $token_details[2];
120 $token = ( new Tokens() )->get_access_token( $user_id );
121 $time_diff = (int) \Jetpack_Options::get_option( 'time_diff' );
122 $jetpack_signature = new \Jetpack_Signature( $token->secret, $time_diff );
123
124 $signature = $jetpack_signature->sign_request(
125 $a_headers['token'],
126 $a_headers['timestamp'],
127 $a_headers['nonce'],
128 $a_headers['body-hash'],
129 $method,
130 $url,
131 $data,
132 false
133 );
134
135 if ( $signature && ! is_wp_error( $signature ) ) {
136 return $signature;
137 } elseif ( is_wp_error( $signature ) ) {
138 $this->log_new_signature_error( $signature->get_error_message() );
139 }
140 } else {
141 $this->log_new_signature_error( 'Malformed token on Authorization Header' );
142 }
143 } else {
144 $this->log_new_signature_error( 'Error extracting Authorization Header' );
145 }
146 } else {
147 $this->log_new_signature_error( 'Empty Authorization Header' );
148 }
149 }
150
151 /**
152 * Logs error if the attempt to create a new signature fails
153 *
154 * @param string $message The error message.
155 * @return void
156 */
157 private function log_new_signature_error( $message ) {
158 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
159 error_log( sprintf( "SANDBOXING: Error re-signing the request. '%s'", $message ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
160 }
161 }
162
163 /**
164 * Extract the values in the Authorization header into an array
165 *
166 * @param array $headers The headers of the request about to be made.
167 * @return array|null
168 */
169 public function extract_authorization_headers( $headers ) {
170 if ( ! empty( $headers['Authorization'] ) && is_string( $headers['Authorization'] ) ) {
171 $header = str_replace( 'X_JETPACK ', '', $headers['Authorization'] );
172 $vars = explode( ' ', $header );
173 $result = array();
174 foreach ( $vars as $var ) {
175 $elements = explode( '"', $var );
176 if ( count( $elements ) === 3 ) {
177 $result[ substr( $elements[0], 0, -1 ) ] = $elements[1];
178 }
179 }
180 return $result;
181 }
182 }
183
184 /**
185 * Modifies parameters of request in order to send the request to the
186 * server specified by `JETPACK__SANDBOX_DOMAIN`.
187 *
188 * Attached to the `requests-requests.before_request` filter.
189 *
190 * @param string $url URL of request about to be made.
191 * @param array $headers Headers of request about to be made.
192 * @param array|string $data Data of request about to be made.
193 * @param string $type Type of request about to be made.
194 * @return void
195 */
196 public function server_sandbox( &$url, &$headers, &$data = null, &$type = null ) {
197 if ( ! Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ) ) {
198 return;
199 }
200
201 $original_url = $url;
202
203 $request_parameters = $this->server_sandbox_request_parameters( Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ), $url, $headers, $data, $type );
204
205 $url = $request_parameters['url'];
206
207 if ( $request_parameters['host'] ) {
208 $headers['Host'] = $request_parameters['host'];
209
210 if ( $request_parameters['new_signature'] ) {
211 $headers['Authorization'] = preg_replace( '/signature=\"[^\"]+\"/', 'signature="' . $request_parameters['new_signature'] . '"', $headers['Authorization'] );
212 }
213
214 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
215 error_log( sprintf( "SANDBOXING via '%s': '%s'", Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ), $original_url ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
216 }
217 }
218 }
219
220 /**
221 * Adds a "Jetpack API Sandboxed" item to the admin bar if the JETPACK__SANDBOX_DOMAIN
222 * constant is set.
223 *
224 * Attached to the `admin_bar_menu` action.
225 *
226 * @param \WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
227 */
228 public function admin_bar_add_sandbox_item( $wp_admin_bar ) {
229 if ( ! Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ) ) {
230 return;
231 }
232
233 $node = array(
234 'id' => 'jetpack-connection-api-sandbox',
235 'title' => 'Jetpack API Sandboxed',
236 'meta' => array(
237 'title' => 'Sandboxing via ' . Constants::get_constant( 'JETPACK__SANDBOX_DOMAIN' ),
238 ),
239 );
240
241 $wp_admin_bar->add_menu( $node );
242 }
243 }
244