WordPressのデフォルト設定では、SVGやJSONといった一部のファイル形式はセキュリティ上の理由からアップロードできない仕様になっています。しかし、開発や運用の現場ではこれらのファイルを扱う必要があるケースも少なくありません。この記事では、WordPressのメディアアップローダーにSVGやJSONなどの独自のファイル種別を許可する方法を解説します。
アップロードを許可するファイル拡張子を追加する
まずは、テーマのfunctions.phpに以下のコードを追加して、SVGやJSONなどのファイルをアップロード可能にします。
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のアップロードを許可することもできます。
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*イベント属性を除去する最低限のサニタイズ処理の例です。
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ファイルを正しく処理できるようにします。
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);
wp_check_filetype_and_extフィルターには、WordPress 5.1以降で追加された5番目の引数$real_mime(ファイルの実際の中身から検出したMIMEタイプ)があります。拡張子だけでなくこの値も確認することで、拡張子を偽装したファイルへの耐性を高められます。よくある質問(FAQ)
まとめ
WordPressでは、デフォルトで制限されているSVGやJSONなどのファイル形式も、フィルターを利用すれば簡単にアップロード可能にすることができます。ただし、SVGについてはセキュリティ上のリスクもあるため、権限による制限だけでなく、内容のサニタイズも含めた運用方針を導入することが重要です。
開発案件やカスタムテーマ制作において、柔軟なメディア管理を行うためにぜひ活用してください。

