2017年3月7日火曜日

【備忘録】WordPress 4.7.3 で修正されたメディアアップロードの中身

【備忘録】WordPress 4.7.1 よりメディアアップロード時のMIMEチェックにファイル本体のチェック機能が付与されていた・・・ で finfo_open 関数の問題でアップロードできないファイルが出てきた問題について、
にて、WordPress 4.7.3で修正されるよ〜という情報があったわけですが、実際にはどうなったのでしょうか。
をみても、原文にも書かれてません。
ならばとコードをチェックしてみました。


wp-include/functions.php
2316行〜2334行 ( wp_check_filetype_and_ext 関数内)

の部分ですね。
そして今回変更があったのは、 2322〜2333行でした。

変更前


If ($real_mime !== $type) {
  $type = ext = false;
}

finfo_open でアップロードされたファイルのコンテンツをチェックした上でのMIMEタイプ($real_mime)と、アップロードされたファイルの拡張子に割り当てられたMIMEタイプ($type)とが一致しなければ、セキュリティを理由のブロックしていました。


変更後


if ( $real_mime && ( $real_mime !== $type ) && ( 0 === strpos( $real_mime, 'application' ) ) ) {
    $allowed = get_allowed_mime_types();
    if ( ! in_array( $real_mime, $allowed ) ) {
            $type = $ext = false;
    }
}

  1. finfo_open でアップロードされたファイルの中身をチェックし、MIMEタイプデータ($real_mime)がある。
  2. 「1」のMIMEタイプ($real_mime)とアップロードされたファイルの拡張子に割り当てられたMIMEタイプ($type)と一致しない
  3. 「1」のMIMEタイプ($real_mime)データが「application」から始まる場合
  4. 「1」のMIMEタイプ($real_mime)が、WordPress のMIMEタイプ($allowed)に登録されていない

この4つの条件を「すべて」満たす場合のみ、セキュリティを理由にブロックする。

と変更されていますね。
つまり変更後は、このMIMEチェックがかなり限定されてますね。
  • アップロードしたファイルの中身と拡張子が一致しない場合、中身チェックのMIMEが application の時のみ、WordPressに登録されたMIMEかどうかチェックする

具体例


テキストデータ(sample.txt)の拡張子だけ pdfに変更(sample.pdf)し、これをアップロードしてみました。

  • finfo_open でのMIMEタイプは「text/plain」($real_mime)
  • アップロードファイルの拡張子に割り当てられたMIMEタイプは「application/pdf」($type)

となります。このケースでは、変更後にはアップロードできちゃいます。
なぜなら、「3」の条件に当てはまらないから(finfo_open でチェックしたMIMEタイプ が application で始まってないから)。

もちろん、今回紹介したチェックは finfo_open を使ったチャックの部分であり、それ以前に、WordPressに登録されたMIMEの拡張子以外はアップロードできないようチェックがあります。
なので、sample.jpeg2002 とか適当な拡張子にしてもアップロードはできませぬ。
まぁただ、 sample.png を sample.txt にしてもアップロードできちゃいますけどね、、、このあたりは WordPress 4.7.1以前に戻ったよ〜って感じでしょうね。

2017年3月7日 @kimipooh