WordPressは何も手を加えない通常の状態では、メディアにアップロードした画像が、外部からでも閲覧できてしまいます。
「画像くらい別にアクセスされても良いんじゃないの?」と思う方も多いと思いますが、実は意外と落とし穴が隠されていたりします。
なぜメディアファイルへの直リンクを禁止する必要があるのか
WordPressサイトの運営において、セキュリティ対策は欠かせません。
特にメディアファイルへの直リンクを禁止することで、サイトのパフォーマンス向上や不正アクセスの防止が可能です。
メディアファイルへの直リンクが許可されていると、他のサイトやユーザーがあなたのサーバーから直接ファイルを表示できるため、サーバー負荷が増大し、サイトの速度低下や帯域の浪費を招く可能性があります。
また、WordPressで会員制のサイトを運営している場合、会員限定コンテンツの中に添付している画像が非会員ユーザーにも閲覧可能になっている状態と言うのは「URLを知らなければアクセスしようがない」とはいえ、あまり好ましくないでしょう。
本記事では、WordPressサイトでメディアファイルへの直リンクを禁止するための具体的な方法を紹介します。
直リンクを防止する具体的な手順
.htaccessファイルに直接記述する
WordPressのルートディレクトリ(wp-contentなどと同じ階層)にある「.htaccess」ファイルを編集します。
「.htaccess」ファイルの編集は正しく行わないとウェブサイト全体に影響を与える可能性があります。
必ずバックアップを取得し、可能であればテスト環境等で実際の挙動を確認してから本番環境へ反映するようにしましょう
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png|pdf)$ [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://example.com [NC]
RewriteRule \.(gif|jpe?g?|png|pdf)$ - [F,NC,L]
</IfModule>
RewriteEngine On
: mod_rewriteエンジンをオンにします。
RewriteCond %{REQUEST_FILENAME} -f:
リクエストされたファイルが実際に存在することを確認します。
RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png|pdf)$ [NC]:
リクエストされたファイルが指定された拡張子の画像ファイルであることを確認します。
RewriteCond %{HTTP_REFERER} !^http(s)?://example.com [NC]
:リクエストのリファラが http(s)://example.com
ドメインからのものでないことを確認します。
RewriteRule \.(gif|jpe?g?|png|pdf)$ - [F,NC,L]:
条件がすべて満たされた場合、403 Forbiddenエラーを返します。
つまり、リンク元が画像ファイルと同一ドメインでなければ、画像ファイルへのアクセスは「403 Forbidden」が返されるというわけです。
この記述により、例えば、「どこかの掲示板に画像URLが勝手に貼られていた」「画像のURLを直接ブラウザに入力してアクセス」などによって画像が閲覧されることを防ぐことが可能になります。
All-In-One Security (AIOS)プラグインを使用して、.htaccessファイルを編集する
もう一つの方法として、WordPressのAll-In-One Security (AIOS)プラグインを使用する方法もあります。
こちらのプラグインの中の「FileSecurity」⇒「FileProtection」の中にある「直リンクの防止」機能をONにすることで、適用することが可能です。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png)$ [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?:/example.jp/ [NC]
RewriteRule \.(gif|jpe?g?|png)$ - [F,NC,L]
</IfModule>
この機能をONにすることで.htaccessには下記のような記述が自動的に追加されます。
見てみるといくつか問題点があることが分かります。
まず「(gif|jpe?g?|png)」という部分ですが、この場合pdfファイルやその他の形式のファイルは直リンク防止の対象になりません。
追加したいファイル形式がある場合は、ご自分で拡張子を追加で記述る必要があります。
次に、「RewriteCond %{HTTP_REFERER} !^$」という記述ですが、これは「リファラが空ではない場合」を意味します。
つまり、画像のURLを直接ブラウザに入力してアクセスされた場合は保護の対象になりません。
個人的には、この1行が不要だと思うので削除してしまって良いでしょう。
画像やPDFファイルのリンクを「新しいタブで開く」で設定している場合
基本的には上記の方法で、外部からの直リンクを防止対策は完了します。
しかしながら、WordPressのコンテンツ内にリンクとして画像を埋め込んでいて、尚且つ「新しいタブで開く」にチェックを付けている場合、実はこれも直リンク防止の対象となり「403 Forbidden」が返されてしまいます。
「新しいタブで開く」にチェックを付けている場合、aタグにはデフォルトで「rel=”noreferrer”」というものが付与されます。
これは「リファラを送信しない」という意味になり、先ほどの.htaccessに記述した「RewriteCond %{HTTP_REFERER} !^http(s)?://example.com [NC]」の部分の条件に該当してしまいます。
リファラ情報が送信されない=同一ドメインからのアクセスではない
という判定をされてしまう訳です。
というわけで、ここで一工夫です。
function removeNoreferrer() {
let links = document.querySelectorAll('a[target="_blank"][rel*="noreferrer"]');
const fileExtensions = [".pdf", "jpg", "png", "gif"];
links.forEach((link) => {
fileExtensions.forEach((fileExtension) => {
if (link.href.endsWith(fileExtension)) {
link.rel = link.rel.replace("noreferrer", "").trim();
if (link.rel === "") {
link.removeAttribute("rel");
}
}
});
});
}
Javascriptを使って、「リンクが.pdf,.jpg,.gif,pngの場合にはnoreferrerを削除する」という記述を加えてみます。
この処理によって、画像を「新しいタブで開く」とした場合でも、リファラが送信され同一ドメインであると認識されるので正常に画像を閲覧することが可能となります。