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