WordPressで公開前の画像をのぞき見から守る

WordPressに画像などをアップロードした場合、それを載せるはずの記事の公開前に画像をのぞき見される場合がある。
ファイル名の推測で画像のパスにあたりをつけたり、添付ファイルページの引数のattachment_idに連番を指定してアクセスするなど。

単なる個人サイトではそこまでする必要は無いが、メディアサイトなどではちょっと勘弁して欲しいところなので、ファイル名の難読化や添付ファイルページの無効化などで対処する。

ファイル名の難読化

テーマのfunctions.phpにファイル名難読化のコードを追加する。

function rename_file_md5($file_name) {
    $parts = explode('.', $file_name);
    $parts[0] = md5(time() . $parts[0]);
    $renamed_file_name = implode('.', $parts);

    return strtolower($renamed_file_name);
}
add_filter('sanitize_file_name', 'rename_file_md5', 10, 2);

保存時にmd5をかける。
元のファイル名が同じものを上げようとしても名前が衝突しないようにtime()を加える。

ちなみに難読化しないと http://www.example.com/wp-content/uploads/yyyy/mm/hoge.jpg といったURLにファイルが無防備に存在することになるため、ファイル名推測でアクセスされる可能性がある。

添付ファイルページの表示を無効化

次にAttachment Pages Redirectというプラグインで添付ファイルページへのアクセスをトップページか親の投稿へとリダイレクトすることで、添付ファイルページが表示されないようにする。

これでファイルへの直接アクセスを防止できる。

少し解説すると、WordPressでは index.phpにattachment_idを引数と指定してアクセスすることで添付ファイルページが表示される。デフォルトではここに画像が表示される。
このattachment_idを連番で回していくと、ファイルがある場合は添付ファイルページが表示されるので、未公開の画像をゲッツできる。
なので画像を守るためには添付ファイルページを表示させない措置が必要となる。

なお単に空のattachment.phpやimage.phpなど添付ファイルを扱うテンプレートを設置するだけでも画像の表示は防げるが、この時index.php?attachment_id=xxxxというURLでのアクセスが、画像名を含んだ添付ファイルページのパーマリンクへとリダイレクトされる。
このパーマリンクにはファイル名の拡張子より前が用いられるので、最初のファイル名の難読化が無意味と化し、ファイルのパスを割り出すヒントとなってしまう。

なのでその前にまるっとリダイレクトして、添付ファイルページのパーマリンクを知らせないことも肝要となってくる。

添付ファイルページを利用している場合は

添付ファイルページをサイトの要素として使っており画像を表示している場合、Attachment Pages Redirectなどで単純に添付ファイルページを無効にすることはできない。

その場合はAttachment Pages Redirectのコードを参考にしつつ、親になる投稿の公開状態を見て添付ファイルページを表示するかしないかをコントロールすると良いかもだ。