Skip to content

Commit

Permalink
Make sure the oembed proxy route applies the WP Embed security mechan…
Browse files Browse the repository at this point in the history
…ism.

- Include the wp-embed.js script only once into the WP Editor.
- Add a temporary filter to make sure the HTML is run through the oembed sanitisation routines.
- Use a specific wrapper for WordPress Embeds.
  • Loading branch information
imath committed Feb 21, 2018
1 parent 25de703 commit 86dbc73
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 11 deletions.
30 changes: 20 additions & 10 deletions blocks/library/embed/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,13 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k
return;
}
response.json().then( ( obj ) => {
const { html, type, provider_name: providerName } = obj;
const { html, provider_name: providerName } = obj;
const providerNameSlug = kebabCase( toLower( providerName ) );
let { type } = obj;

if ( includes( html, 'class="wp-embedded-content" data-secret' ) ) {
type = 'wp-embed';
}
if ( html ) {
this.setState( { html, type, providerNameSlug } );
setAttributes( { type, providerNameSlug } );
Expand Down Expand Up @@ -194,6 +198,20 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k
const parsedUrl = parse( url );
const cannotPreview = includes( HOSTS_NO_PREVIEWS, parsedUrl.host.replace( /^www\./, '' ) );
const iframeTitle = sprintf( __( 'Embedded content from %s' ), parsedUrl.host );
const embedWrapper = 'wp-embed' === type ? (
<div
className="wp-block-embed__wrapper"
dangerouslySetInnerHTML={ { __html: html } }
/>
) : (
<div className="wp-block-embed__wrapper">
<SandBox
html={ html }
title={ iframeTitle }
type={ type }
/>
</div>
);
let typeClassName = 'wp-block-embed';
if ( 'video' === type ) {
typeClassName += ' is-video';
Expand All @@ -207,15 +225,7 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k
<p className="components-placeholder__error"><a href={ url }>{ url }</a></p>
<p className="components-placeholder__error">{ __( 'Previews for this are unavailable in the editor, sorry!' ) }</p>
</Placeholder>
) : (
<div className="wp-block-embed__wrapper">
<SandBox
html={ html }
title={ iframeTitle }
type={ type }
/>
</div>
) }
) : embedWrapper }
{ ( caption && caption.length > 0 ) || isSelected ? (
<RichText
tagName="figcaption"
Expand Down
2 changes: 1 addition & 1 deletion lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ function gutenberg_register_scripts_and_styles() {
wp_register_script(
'wp-edit-post',
gutenberg_url( 'edit-post/build/index.js' ),
array( 'jquery', 'heartbeat', 'wp-element', 'wp-components', 'wp-editor', 'wp-i18n', 'wp-date', 'wp-utils', 'wp-data' ),
array( 'jquery', 'heartbeat', 'wp-element', 'wp-components', 'wp-editor', 'wp-i18n', 'wp-date', 'wp-utils', 'wp-data', 'wp-embed' ),
filemtime( gutenberg_dir_path() . 'edit-post/build/index.js' ),
true
);
Expand Down
46 changes: 46 additions & 0 deletions lib/compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,49 @@ function gutenberg_register_rest_api_post_type_capabilities() {
);
}
add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_type_capabilities' );

/**
* Make sure oEmbed REST Requests apply the WP Embed security mechanism for WordPress embeds.
*
* @see https://core.trac.wordpress.org/ticket/32522
*
* TODO: This is a temporary solution. Next step would be to edit the WP_oEmbed_Controller,
* once merged into Core.
*
* @since 2.3.0
*
* @param WP_HTTP_Response|WP_Error $response The REST Request response.
* @param WP_REST_Server $handler ResponseHandler instance (usually WP_REST_Server).
* @param WP_REST_Request $request Request used to generate the response.
* @return WP_HTTP_Response|object|WP_Error The REST Request response.
*/
function gutenberg_filter_oembed_result( $response, $handler, $request ) {
if ( 'GET' !== $request->get_method() ) {
return $response;
}

if ( is_wp_error( $response ) && 'oembed_invalid_url' !== $response->get_error_code() ) {
return $response;
}

// External embeds.
if ( '/oembed/1.0/proxy' === $request->get_route() ) {
if ( is_wp_error( $response ) ) {
// It's possibly a local post, so lets try and retrieve it that way.
$post_id = url_to_postid( $_GET['url'] );
$data = get_oembed_response_data( $post_id, apply_filters( 'oembed_default_width', 600 ) );

if ( ! $data ) {
// Not a local post, return the original error.
return $response;
}
$response = (object) $data;
}

// Make sure the HTML is run through the oembed sanitisation routines.
$response->html = wp_oembed_get( $_GET['url'], $_GET );
}

return $response;
}
add_filter( 'rest_request_after_callbacks', 'gutenberg_filter_oembed_result', 10, 3 );

0 comments on commit 86dbc73

Please sign in to comment.