【WordPress】メディアアップローダーに独自のファイル種別(SVG・JSONなど)を許可する方法

【WordPress】メディアアップローダーに独自のファイル種別(SVG・JSONなど)を許可する方法 WordPress

WordPressのデフォルト設定では、SVGやJSONといった一部のファイル形式はセキュリティ上の理由からアップロードできない仕様になっています。しかし、開発や運用の現場ではこれらのファイルを扱う必要があるケースも少なくありません。この記事では、WordPressのメディアアップローダーにSVGやJSONなどの独自のファイル種別を許可する方法を解説します。

スポンサーリンク

アップロードを許可するファイル拡張子を追加する

まずは、テーマのfunctions.phpに以下のコードを追加して、SVGやJSONなどのファイルをアップロード可能にします。

functions.php:MIMEタイプの追加
function custom_mime_types($mimes) {
  $mimes['svg']  = 'image/svg+xml';
  $mimes['json'] = 'application/json';
  return $mimes;
}
add_filter('upload_mimes', 'custom_mime_types');

このコードは、WordPressのupload_mimesフィルターを使用して、許可するMIMEタイプ(MIME種類)にSVGとJSONを追加しています。

SVGファイルに関する注意点

SVGはXMLベースで記述されており、JavaScriptを埋め込むことも可能なため、セキュリティリスクが存在します。信頼できるユーザーのみにアップロードを許可するか、SVGの内容を検査するような対策を組み合わせることが推奨されます。

より安全にSVGを扱いたい場合は、次のように管理者のみにSVGのアップロードを許可することもできます。

functions.php:管理者のみSVGを許可
function restrict_svg_upload_to_admin($mimes) {
  if (current_user_can('manage_options')) {
    $mimes['svg'] = 'image/svg+xml';
  }
  return $mimes;
}
add_filter('upload_mimes', 'restrict_svg_upload_to_admin');

ロールの判定にはcurrent_user_can(‘manage_options’)のような権限(capability)ベースの判定を使うのがおすすめです。カスタムロールを追加した場合でも、権限さえ揃っていれば正しく判定できます。

アップロードされたSVGの中身をサニタイズする

アップロードを許可するだけでは、悪意のあるスクリプトを含むSVGもそのまま受け入れてしまいます。以下は、DOMDocumentを使ってscript要素とon*イベント属性を除去する最低限のサニタイズ処理の例です。

functions.php:SVGの簡易サニタイズ
function sanitize_svg_on_upload($file) {
  if ($file['type'] !== 'image/svg+xml') {
    return $file;
  }

  $content = file_get_contents($file['tmp_name']);

  libxml_use_internal_errors(true);
  $dom = new DOMDocument();
  if (!$dom->loadXML($content)) {
    $file['error'] = '不正なSVGファイルです。';
    return $file;
  }

  // <script>要素を削除
  foreach (iterator_to_array($dom->getElementsByTagName('script')) as $script) {
    $script->parentNode->removeChild($script);
  }

  // on*イベント属性を削除
  $xpath = new DOMXPath($dom);
  foreach (iterator_to_array($xpath->query('//@*[starts-with(name(), "on")]')) as $attr) {
    $attr->ownerElement->removeAttribute($attr->nodeName);
  }

  file_put_contents($file['tmp_name'], $dom->saveXML());
  return $file;
}
add_filter('wp_handle_upload_prefilter', 'sanitize_svg_on_upload');
これは最低限の対策であり、本番運用には専用プラグインを推奨
上記のサニタイズ処理は<script>要素とon*イベント属性の除去のみを行う簡易的なものです。SVGにはCSS経由での攻撃や外部リソース参照など、他にも注意すべき攻撃手法が存在するため、本番環境で不特定多数からのアップロードを受け付ける場合は、SVGサニタイズを専門に行うプラグイン(例:Safe SVG)の利用を検討してください。

アップロード時のエラーを防ぐための設定

WordPressバージョンやサーバー環境によっては、MIMEタイプのチェックによりエラーが出る場合があります。以下のようにwp_check_filetype_and_extをカスタマイズして、SVGファイルを正しく処理できるようにします。

functions.php:SVGのMIMEタイプ判定を補正
function fix_svg_mime_type($data, $file, $filename, $mimes) {
  $ext = pathinfo($filename, PATHINFO_EXTENSION);
  if ($ext === 'svg') {
    $data['ext']  = 'svg';
    $data['type'] = 'image/svg+xml';
  }
  return $data;
}
add_filter('wp_check_filetype_and_ext', 'fix_svg_mime_type', 10, 4);
$real_mimeも活用するとより安全
wp_check_filetype_and_extフィルターには、WordPress 5.1以降で追加された5番目の引数$real_mime(ファイルの実際の中身から検出したMIMEタイプ)があります。拡張子だけでなくこの値も確認することで、拡張子を偽装したファイルへの耐性を高められます。

よくある質問(FAQ)

QWordPressにSVGファイルのアップロードを許可するには?
Aupload_mimes フィルターでSVG MIMEタイプを追加します。ただしSVGはXSSリスクがあるため、wp_handle_upload_prefilterでscript要素やon*属性を除去するサニタイズ処理を追加するか、信頼できるユーザーのみに許可します。
QJSONファイルのアップロードを許可するには?
Aupload_mimesフィルターでarray(‘json’ => ‘application/json’)を追加します。SVGと同様にセキュリティリスクを考慮して使用するロールを制限することが推奨です。
Qアップロードを特定のユーザーロールに限定するには?
Awp_handle_upload_prefilterでcurrent_user_can()を確認し、許可しないファイル形式をアップロードしようとした場合は$file[‘error’]にエラーメッセージを設定して返します。

まとめ

WordPressでは、デフォルトで制限されているSVGやJSONなどのファイル形式も、フィルターを利用すれば簡単にアップロード可能にすることができます。ただし、SVGについてはセキュリティ上のリスクもあるため、権限による制限だけでなく、内容のサニタイズも含めた運用方針を導入することが重要です。

開発案件やカスタムテーマ制作において、柔軟なメディア管理を行うためにぜひ活用してください。