このページの本文へ

oEmbed機能の仕組みに見る、WordPressが圧倒的に安全な理由

2016年09月15日 04時00分更新

文●David Attard

  • この記事をはてなブックマークに追加
本文印刷
WordPressを使っていて便利なのが、YouTubeやTwitterのURLをペーストするだけで埋め込めること。ただ便利なだけでなく、安全性にも気を配った仕組みなのです。

自分のWordPressのサイトにいつも投稿している人なら、外部コンテンツを埋め込む必要を頻繁に感じていることでしょう。

YouTubeやVimeoからの動画、SoundCloudやSpotifyからのミュージッククリップ、TweetやVine、Instagram上のFlickr、なんであれ、あっという間に埋め込めます。埋め込みたいコンテンツのURLをWordPressの記事にコピー&ペーストするだけで完成です。

この記事では、WordPressの「embed」(埋め込み)と「oEmbed」機能に関する詳細をすべて、徹底的に紹介します。

WordPressに「embed」機能が必要な理由

これまで使ってきたほかのCMSに比べてWordPressの使い勝手がとても良い点の1つは、外部メディアが簡単に埋め込めることです。

名指しはしませんが、世間一般でもっともポピュラーなCMSの1つ(WordPress以外の)を使って、YouTubeビデオを記事に埋め込もうとすると、「果てしない悪夢」となる場合があります。

:これは提言であって、皮肉を言うつもりはありません。記事へのYouTube動画の埋め込みは、どのCMSでも簡単にできるはずです。

なぜこんなことが起きるのでしょうか?

実は、外部コンテンツの埋め込みには、えてして潜在的なセキュリティ問題があります。コンテンツは一般に、iFrame(インラインフレーム)を使って埋め込まれます。簡単に言うとiFrameとは、外部機能を参照できる新しい「ウィンドウ」のことです。

たとえばYouTubeから動画を埋め込もうとする場合、次の構文を使う必要があります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/aDorTBEhEtk" frameborder="0" allowfullscreen></iframe>

この構文のどこが問題なのでしょうか?

実際、このコード自体になにも悪いところはありません。とはいえ、自分の投稿に、どんな人にもiFrameの埋め込みを許可することになり、これには重大なセキュリティ上のリスクがあります。

「それがどうしてセキュリティ上のリスクになるのか」と聞きたくなるかもしれません。

YouTubeの埋め込みにiFrameを使うと、うまくいく一方で、iFrameはどんなサイトの参照にも使われてしまう可能性があります。実際、悪意のあるユーザーが、マルウェアを含むサイトを参照するiFrameを埋め込む場合もあるのです。

そのうえ、iFrameはピクセルサイズを0 × 0(目に見えないドット)にして隠せるので、そうなると少なくとも肉眼での検知がとても難しくなります。

こういうわけで、iFrameはユーザー入力の許可される領域では勧められません。

ほかのCMSでWordPressがサポートできるタイプの埋め込みを使える場合、次のどちらかの方法で外部メディアを埋め込めます。

  1. サードパーティのプラグインを使う
  2. iFrameの埋め込みを許可する(結果として潜在的なセキュリティリスクが発生する)

実際、WordPressのembed機能を使う場合でも、信頼できるサードパーティサービスのみを使用できます。(WordPressには)使えるサービスと、使えないサービスを決定する内部ホワイトリストがあります。これを使えば、潜在的なセキュリティ問題を軽減できます。

WordPressのembed機能の動作

WordPressのembed機能がサポートしているサービスはたくさんあります。embedでサポートされるサービスの一覧はこちらで確認できます。

WordPressのembed機能は、oEmbed APIの実装によって動作し、基本的にこの方法で、プロバイダー(YouTubeなど)から埋め込まれたコンテンツを利用者のWebサイト(WordPressなど)で表示できます。

利用者はプロバイダーにHTTPリクエストを送信し、プロバイダーは利用者のWebサイトにメディアの埋め込みが可能な方法で構築されたデータを格納したJSONやXML HTTPレスポンスで応答します。

リクエストは以下のとおりです。

http://www.youtube.com/oembed?url=http%3A//youtube.com/watch%3Fv%3DM3r2XDceM6A&format=json

レスポンスは、次のようになります。

{"html": "\u003ciframe width=\"480\" height=\"270\" src=\"https:\/\/www.youtube.com\/embed\/M3r2XDceM6A?feature=oembed\" frameborder=\"0\" allowfullscreen\u003e\u003c\/iframe\u003e", "thumbnail_height": 360, 
"thumbnail_width": 480, 
"title": "Amazing Nintendo Facts", 
"width": 480, 
"height": 270, 
"type": "video", 
"provider_url": "https:\/\/www.youtube.com\/", 
"thumbnail_url": "https:\/\/i.ytimg.com\/vi\/M3r2XDceM6A\/hqdefault.jpg", 
"author_name": "ZackScott", "
author_url": "https:\/\/www.youtube.com\/user\/ZackScott", "version": "1.0", 
"provider_name": "YouTube"}

もちろん、このやり取りはバックヤードで実行されます。

メディアをWordPressに埋め込む

WordPressのバックヤード機能を理解したところで、WordPressの投稿記事に埋め込めるメディアの例をいくつか見ていきます。

おそらく、多くの人ははすでにYouTube動画を埋め込んだ経験があるでしょう。

YouTube動画の埋め込みに関する次のような一般的な構文を使わなくても、

<iframe width="560" height="315" src="https://www.youtube.com/embed/O_Bw1_0u1P8" frameborder="0" allowfullscreen></iframe>

次のようにYouTube動画のURLを取得し、投稿記事にペーストするだけでOKです。

https://www.youtube.com/watch?v=O_Bw1_0u1P8

WordPress embed YouTube video

できあがりです。

埋め込んだはずの動画がハイパーリンクに置きかえられていないかどうか確かめてください。

エディターで動画のプレビューが確認できます。

投稿記事が有効になると、埋め込まれたYouTube動画を確認できます。

次に、投稿記事にTweetを埋め込みます。埋め込みたいTweetを見つけ、図のように3点リーダーをクリックしてリンクを取得し、WordPressの投稿記事に挿入してください。

WordPress embed link to Tweet

結果は次のようになります。

WordPress embed Twitter

このすべては、タグや「blockquote」「iFrame」などに触れなくても自動的に実行されます。

SoundCloudファイルを投稿記事に埋め込みます。これも、埋め込みたいファイルのURLを取得して投稿記事にペーストするだけです。

https://soundcloud.com/versioningshow/ver002-mat-marquis-on-the-versionong-show

下のスクリーンショットで確認できるように、URLを投稿記事に埋め込むと、すぐに埋め込み処理中のファイルのプレビューが取得されます。

Embed SoundCloud WordPress

ほかにもいろいろな例がありますが、もうポイントをつかめたに違いありません。

スタイリング:埋め込みメディアの(最大)サイズを設定する

原則として、スタイリングに求められることはあまりありません。 WordPressのoEmbed機能は、スタイリングの大半を提供できます。レスポンシブなテーマにも対応してくれるので、どちらにしてもまったく心配いりません。

とはいえ、埋め込むメディアの実際のサイズ指定は多少必要な場合があります。

WordPressのoEmbed機能は、Embedショートコードの処理によって実現されます。

Embedショートコードで、1つのメディアの最大寸法を設定できます。もちろん、投稿をレスポンシブにしておくことが望まれるので、寸法は固定されません。

004

ほかのサイトからのメディアの埋め込みを許可する

先ほどセキュリティ上の理由から、WordPressにはどんなサイトからでもメディアを埋め込めるわけではないと書きました。

とはいえ、サポート外のWebサイトからメディアを埋め込むことも可能です。

そのためには、埋め込むサイトを内部ホワイトリストに追加する必要があります。

これには2つの方法があり、どちらを使うかはサイトがoEmbed APIに対応しているかどうかによって決まります。

oEmbed API対応のサイトを追加する

埋め込みを許可するテーマやプラグインの「functions.php」ファイルでwp_oembed_add_provider関数を呼び出し、embedプロバイダーのホワイトリストに新しいサイトを追加します。

<?php wp_oembed_add_provider( $format, $provider, $regex ); ?>

たとえば次のようになります。

<?php wp_oembed_add_provider( 'http://example.com/watchvideo/*', 'http://example.com/oembedprovider' ); ?>

メディアが複数の異なるURLで埋め込まれる場合、正規表現を使ってそれら異なるURLが許可されることを記述できます。仮に、サイトに正規表現を含めて「TheNewTube」を追加すると考えるとき、次のコードを使用できます。

<?php wp_oembed_add_provider( '#http://(www\.)?thenewtube\.com/watch.*#i', 'http://www.thenewtube.com/oembed', true ); ?>

oEmbed API対応外のサイトを追加する

oEmbed対応外のサイトを追加する場合、プロバイダーとしての追加が可能です。

ここでも「functions.php」ファイルで、「wp_embed_register_handler」を使ってサイトを登録する必要があります。

<?php wp_embed_register_handler( $id, $regex, $callback, $priority ); ?>

メディアの埋め込みに必要なHTMLの生成に使用される、コールバック関数の追加も必要です。

WordPressのコーデックスでは、ForbesのWebサイトから動画を埋め込む方法例が次のように提供されています。

<?php

wp_embed_register_handler( 'forbes', '#http://(?:www|video)\.forbes\.com/(?:video/embed/embed\.html|embedvideo/)\?show=([\d]+)&format=frame&height=([\d]+)&width=([\d]+)&video=(.+?)($|&)#i', 'wp_embed_handler_forbes' );

function wp_embed_handler_forbes( $matches, $attr, $url, $rawattr ) {

    $embed = sprintf(
            '<iframe src="http://www.forbes.com/video/embed/embed.html?show=%1$s&format=frame&height=%2$s&width=%3$s&video=%4$s&mode=render" width="%3$spx" height="%2$spx" frameborder="0" scrolling="no" marginwidth="0" marginheight="0"></iframe>',
            esc_attr($matches[1]),
            esc_attr($matches[2]),
            esc_attr($matches[3]),
            esc_attr($matches[4])
            );

    return apply_filters( 'embed_forbes', $embed, $matches, $attr, $url, $rawattr );
}

?>

サイトで上記の処理が必要な場合、WordPressの開発者に相談し、実装してもらうのが最善でしょう。そうすれば、サイトを破壊しかねないバグが入り込まないようにしっかり手配できます。

oEmbedプロバイダーとしてのWordPress(WordPress Version 4.4以降)

ここまで、WordPressについて、もっぱらサードパーティサイトからメディアを利用する立場として考えてきましたが、実際WordPressではoEmbedも利用できるようになりました。

WordPress as oEmbed Provider

4.4以降、WordPressはoEmbedコンテンツのプロバイダーとしても動作可能です。

このことは、自分のWordPressのWebサイトを介して(一般に「example.com/your-post/embed/」のように、URLの末尾に「embed」を追加した短縮パーマネントURLを介して)、サイト上で公開したどんな投稿も、どんなタイプでも、サードパーティのWebサイトに埋め込めることを意味します。

セキュリティ上の理由から、embedはサンドボックス化されたiFrameに置きますが、iFrameのコンテンツはプロバイダーサイト上のテーマによってのみスタイリングや入れ替え可能なテンプレートとなります。

Enbed用の関数とフック

embedに関連した、もっとも便利な4つの関数を紹介します。

oEmbed出力のカスタマイズ

さまざまなテンプレートファイルのカスタマイズと同様に、投稿からのembedテンプレートも「embed_head andembed_footer」を使ってスタイリングし、embedテンプレートのはじめと終わりにカスタムコードを追加できます。

「X-WP-embed:true」に設定すると、テンプレートが使われる際にヘッダーも送信されます。これによってWordPressのoEmbedを利用している任意のアプリケーション内で埋め込みが実行された投稿をターゲットしやすくなります。

要約

この記事で見てきたとおり、WordPressのembed機能はとても広範におよびます。ライターにとっても開発者にとっても、WordPress embedを使用してメディアを埋め込むことによりコンテンツを拡張できる、いろいろな方法があります。

(原文:The Complete Guide to Using WordPress Embeds

[翻訳:新岡祐佳子/編集:Livit

Web Professionalトップへ

WebProfessional 新着記事