From df6eb733eb7fb616d7b82c9a5b0887eb21c473e7 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Mon, 30 Jun 2014 05:48:16 +0000 Subject: [PATCH] Secure embeds in the editor (first run): - When the user pastes an embeddable http URL, try to get the https embed. - If an embed provider doesn't support ssl embeds, show a placeholder/error message. - Revise the way we return error messages. See #28195, #28507. git-svn-id: https://develop.svn.wordpress.org/trunk@28919 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/ajax-actions.php | 41 +++++++++++++++++++++++--- src/wp-admin/includes/misc.php | 12 -------- src/wp-includes/class-wp-embed.php | 10 +++++++ src/wp-includes/js/mce-view.js | 4 ++- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index dff74ec683..44958a070f 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2547,17 +2547,50 @@ function wp_ajax_parse_embed() { wp_send_json_error(); } - if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'read_post', $post->ID ) ) { + if ( empty( $_POST['shortcode'] ) || ! current_user_can( 'edit_post', $post->ID ) ) { wp_send_json_error(); } + $shortcode = $_POST['shortcode']; + $url = str_replace( '[embed]', '', str_replace( '[/embed]', '', $shortcode ) ); + $parsed = false; setup_postdata( $post ); - // If the URL cannot be embedded, return an eror message with wp_send_json_error() - add_filter( 'embed_maybe_make_link', '_wpview_embed_error', 20, 2 ); + $wp_embed->return_false_on_fail = true; - $parsed = $wp_embed->run_shortcode( $_POST['shortcode'] ); + if ( is_ssl() && preg_match( '%^\\[embed\\]http://%i', $shortcode ) ) { + // Admin is ssl and the user pasted non-ssl URL. + // Check if the provider supports ssl embeds and use that for the preview. + $ssl_shortcode = preg_replace( '%^\\[embed\\]http://%i', '[embed]https://', $shortcode ); + $parsed = $wp_embed->run_shortcode( $ssl_shortcode ); + + if ( ! $parsed ) { + $no_ssl_support = true; + } + } + + if ( ! $parsed ) { + $parsed = $wp_embed->run_shortcode( $shortcode ); + } + + if ( ! $parsed ) { + wp_send_json_error( array( + 'type' => 'not-embeddable', + 'message' => sprintf( __( '%s failed to embed.' ), '' . esc_url( $url ) . '' ), + ) ); + } + + // TODO: needed? $parsed = do_shortcode( $parsed ); + if ( ! empty( $no_ssl_support ) || ( is_ssl() && ( preg_match( '%<(iframe|script|embed) [^>]*src="http://%', $parsed ) || + preg_match( '%]*href="http://%', $parsed ) ) ) ) { + // Admin is ssl and the embed is not. Iframes, scripts, and other "active content" will be blocked. + wp_send_json_error( array( + 'type' => 'not-ssl', + 'message' => sprintf( __( 'Preview not available. %s cannot be embedded securely.' ), '' . esc_url( $url ) . '' ), + ) ); + } + wp_send_json_success( $parsed ); } diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php index 17ab62f1c8..9df880581f 100644 --- a/src/wp-admin/includes/misc.php +++ b/src/wp-admin/includes/misc.php @@ -824,15 +824,3 @@ function heartbeat_autosave( $response, $data ) { } // Run later as we have to set DOING_AUTOSAVE for back-compat add_filter( 'heartbeat_received', 'heartbeat_autosave', 500, 2 ); - -/** - * Send error message when an URL cannot be embedded. Used in wp_ajax_parse_embed(). - * - * @access private - * @since 4.0 - */ -function _wpview_embed_error( $output, $url ) { - wp_send_json_error( array( - 'message' => sprintf( __( '%s failed to embed.' ), esc_url( $url ) ), - ) ); -} diff --git a/src/wp-includes/class-wp-embed.php b/src/wp-includes/class-wp-embed.php index fbcd51713f..e959d93590 100644 --- a/src/wp-includes/class-wp-embed.php +++ b/src/wp-includes/class-wp-embed.php @@ -12,6 +12,12 @@ class WP_Embed { public $usecache = true; public $linkifunknown = true; + /** + * When an URL cannot be embedded, return false instead of returning a link + * or the URL. Bypasses the 'embed_maybe_make_link' filter. + */ + public $return_false_on_fail = false; + /** * Constructor */ @@ -322,6 +328,10 @@ class WP_Embed { * @return string Linked URL or the original URL. */ public function maybe_make_link( $url ) { + if ( $this->return_false_on_fail ) { + return false; + } + $output = ( $this->linkifunknown ) ? '' . esc_html($url) . '' : $url; /** diff --git a/src/wp-includes/js/mce-view.js b/src/wp-includes/js/mce-view.js index baaaf72928..cfdf2bd698 100644 --- a/src/wp-includes/js/mce-view.js +++ b/src/wp-includes/js/mce-view.js @@ -737,7 +737,9 @@ window.wp = window.wp || {}; } ) .fail( function( response ) { if ( response && response.message ) { - if ( self.type === 'embed' ) { + if ( ( response.type === 'not-embeddable' && self.type === 'embed' ) || + response.type === 'not-ssl' ) { + self.setError( response.message, 'admin-media' ); } else { self.setContent( '

' + self.original + '

', null, true );