PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 15.0.3
Jetpack – WP Security, Backup, Speed, & Growth v15.0.3
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.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 / unauth-file-upload.php
jetpack Last commit date
3rd-party 11 months ago _inc 20 hours ago css 1 year ago extensions 11 months ago images 1 year ago jetpack_vendor 20 hours ago json-endpoints 11 months ago modules 11 months ago sal 11 months ago src 1 year ago vendor 11 months ago views 11 months ago CHANGELOG.md 11 months ago LICENSE.txt 5 years ago SECURITY.md 2 years ago class-jetpack-connection-status.php 2 years ago class-jetpack-gallery-settings.php 1 year ago class-jetpack-newsletter-dashboard-widget.php 1 year ago class-jetpack-pre-connection-jitms.php 2 years ago class-jetpack-stats-dashboard-widget.php 1 year ago class-jetpack-xmlrpc-methods.php 1 year ago class.frame-nonce-preview.php 1 year ago class.jetpack-admin.php 11 months ago class.jetpack-autoupdate.php 1 year ago class.jetpack-cli.php 11 months ago class.jetpack-client-server.php 2 years ago class.jetpack-gutenberg.php 11 months ago class.jetpack-heartbeat.php 2 years ago class.jetpack-modules-list-table.php 1 year ago class.jetpack-network-sites-list-table.php 1 year ago class.jetpack-network.php 1 year ago class.jetpack-plan.php 3 years ago class.jetpack-post-images.php 1 year ago class.jetpack-twitter-cards.php 1 year ago class.jetpack-user-agent.php 2 years ago class.jetpack.php 11 months ago class.json-api-endpoints.php 11 months ago class.json-api.php 11 months ago class.photon.php 3 years ago composer.json 11 months ago enhanced-open-graph.php 1 year ago functions.compat.php 1 year ago functions.cookies.php 2 years ago functions.global.php 1 year ago functions.is-mobile.php 2 years ago functions.opengraph.php 1 year ago functions.photon.php 2 years ago jetpack.php 20 hours ago json-api-config.php 3 years ago json-endpoints.php 2 years ago load-jetpack.php 1 year ago locales.php 1 year ago readme.txt 20 hours ago unauth-file-upload.php 1 year ago uninstall.php 1 year ago wpml-config.xml 4 years ago
unauth-file-upload.php
163 lines
1 <?php
2 /**
3 * Unauthenticated File Upload Helper Functions.
4 *
5 * @package automattic/jetpack
6 */
7
8 namespace Automattic\Jetpack\UnauthFileUpload;
9
10 if ( ! defined( 'ABSPATH' ) ) {
11 exit( 0 );
12 }
13
14 add_action( 'wp_ajax_jetpack_unauth_file_download', __NAMESPACE__ . '\handle_file_download' );
15 add_filter( 'jetpack_unauth_file_upload_get_file', __NAMESPACE__ . '\get_file_content', 10, 2 );
16 add_filter( 'jetpack_unauth_file_download_url', __NAMESPACE__ . '\filter_get_download_url', 10, 2 );
17
18 /**
19 * Get the file download URL filter callback.
20 *
21 * @param string $url The file download URL.
22 * @param int $file_id The file ID.
23 *
24 * @return string The file download URL.
25 */
26 function filter_get_download_url( $url, $file_id ) {
27 $nonce = wp_create_nonce( 'jetpack_unauth_file_download_nonce_' . $file_id );
28 return add_query_arg(
29 array(
30 'action' => 'jetpack_unauth_file_download',
31 'file_id' => $file_id,
32 '_wpnonce' => $nonce,
33 ),
34 admin_url( 'admin-ajax.php' )
35 );
36 }
37
38 /**
39 * Handle file download requests from the admin page.
40 *
41 * @return never This method never returns as it exits directly
42 */
43 function handle_file_download() {
44 if ( ! current_user_can( 'edit_pages' ) ) {
45 wp_die( esc_html__( 'Sorry, you are not allowed to access this page.', 'jetpack' ) );
46 }
47
48 $file_id = isset( $_GET['file_id'] ) ? absint( wp_unslash( $_GET['file_id'] ) ) : 0;
49
50 if ( ! $file_id ) {
51 wp_die( esc_html__( 'Invalid file request.', 'jetpack' ) );
52 }
53
54 if (
55 ! isset( $_GET['_wpnonce'] ) ||
56 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'jetpack_unauth_file_download_nonce_' . $file_id ) ) {
57 wp_die( esc_html__( 'Invalid nonce.', 'jetpack' ) );
58 }
59
60 /**
61 * Get the file content that we send to the user to download.
62 *
63 * @since 14.6
64 *
65 * @param array $file_content The file content.
66 * @param string $file_id The file ID.
67 *
68 * @return array|\WP_Error The file array, containing the content, name and type.
69 */
70 $file = apply_filters( 'jetpack_unauth_file_upload_get_file', array(), $file_id );
71
72 if ( is_wp_error( $file ) || empty( $file ) ) {
73 wp_die( esc_html__( 'Error retrieving file content.', 'jetpack' ) );
74 }
75
76 $is_preview = isset( $_GET['preview'] ) && 'true' === $_GET['preview'];
77
78 // Clean output buffer
79 if ( ob_get_length() ) {
80 ob_clean();
81 }
82 // Set headers for download
83 header( 'Content-Type: ' . $file['type'] );
84
85 if ( ! $is_preview ) {
86 // Forcing the file to be downloaded is important to prevent XSS attacks.
87 header( 'Content-Disposition: attachment; filename="' . sanitize_file_name( $file['name'] ) . '"' );
88 } else {
89 // For preview mode, use inline disposition
90 header( 'Content-Disposition: inline; filename="' . sanitize_file_name( $file['name'] ) . '"' );
91 }
92 header( 'Content-Length: ' . strlen( $file['content'] ) );
93 header( 'Content-Transfer-Encoding: binary' );
94 header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
95 header( 'Pragma: no-cache' );
96 header( 'Expires: 0' );
97
98 // Output file content and exit
99 echo $file['content']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Binary file data
100 exit( 0 );
101 }
102
103 /**
104 * Get the file content.
105 *
106 * @param array $file_content The file content, name and type.
107 * @param integer $file_id The file ID.
108 * @return array|\WP_Error The file content, name and type
109 */
110 function get_file_content( $file_content, $file_id ) {
111 if ( ( new \Automattic\Jetpack\Status\Host() )->is_wpcom_simple() ) {
112 return $file_content;
113 }
114
115 $blog_id = \Jetpack_Options::get_option( 'id' );
116 $request_url = sprintf( '/sites/%d/unauth-file-upload/%s', $blog_id, $file_id );
117
118 $response = \Automattic\Jetpack\Connection\Client::wpcom_json_api_request_as_blog(
119 $request_url,
120 'v2',
121 array(
122 'method' => 'GET',
123 ),
124 null,
125 'wpcom'
126 );
127
128 $file_content = wp_remote_retrieve_body( $response );
129
130 if ( is_wp_error( $response ) || empty( $file_content ) ) {
131 return new \WP_Error( 'jetpack_unauth_file_upload_error', esc_html__( 'Error retrieving file content.', 'jetpack' ) );
132 }
133
134 try {
135 $content = json_decode( $file_content, true, 3, defined( 'JSON_THROW_ON_ERROR' ) ? \JSON_THROW_ON_ERROR : 0 ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.json_throw_on_errorFound
136 if ( isset( $content['message'] ) ) {
137 return new \WP_Error( 'jetpack_unauth_file_upload_error', esc_html__( 'Error retrieving file content.', 'jetpack' ) );
138 }
139 } catch ( \Exception $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
140 // If the file is not JSON, we assume it's a binary file.
141 }
142
143 $content_disposition = wp_remote_retrieve_header( $response, 'content-disposition' );
144 $filename = '';
145 if ( $content_disposition ) {
146 // Match the filename using a regular expression
147 if ( preg_match( '/filename="([^"]+)"/', $content_disposition, $matches ) ) {
148 $filename = $matches[1]; // Extract the filename
149 }
150 }
151
152 $type = wp_remote_retrieve_header( $response, 'content-type' );
153 if ( empty( $type ) ) {
154 $type = 'application/octet-stream'; // Default to binary if no content type is found
155 }
156
157 return array(
158 'content' => $file_content,
159 'type' => $type,
160 'name' => $filename,
161 );
162 }
163