アップロードされたファイルのMIMEタイプを検証する

アップロードされたファイルが正常か判断するため、MIMEタイプの検出方法について調べて実装したので、情報をまとめます。

MIMEタイプ

MIMEタイプ(Multipurpose Internet Mail Extensions)はファイルの識別子のようなもの。

MIMEタイプにはそのファイルのマジックナンバーというものが含まれていて、バイト構造見ることでファイルタイプを識別できます。

マジックナンバー。バイト構造を見ることで、様々な形式の構文によりファイルタイプを推測することができます。例えば GIF ファイルは16進数の値 47 49 46 38 39 ( GIF89)、 PNG ファイルは 89 50 4E 47 ( .PNG) で始まります。マジックナンバーを持たない種類のファイルもありますので、100%!信(MISSING)頼できるシステムではありません。

https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types

ブラウザで検出しているMIMEタイプ

ブラウザで検出しているMIMEタイプは拡張子で判別しており、バイナリまでチェックしてないようです。そのため拡張子が偽造されたファイルを正確に判別できません。

GoでMIMEタイプを検出する方法

Goのhttpパッケージに DetectContentType というファンクションがあります。

https://golang.org/pkg/net/http/#DetectContentType

node.jsでMIMEタイプを検出する方法

MIMEタイプを検出するnpmパッケージがいくつか見つかりました。

mime はbufferから検出できませんが、 file-type はbufferからの検出ができ、ブラウザからアップロードされたファイルにも対応できます。

file-typeパッケージを利用したMIMEタイプの検出

yarnかnpmでインストールし、下記のように使えます。超簡単でした。

  const fileType = require('file-type')
  const b = await fileType.fromBuffer(buffer)
  console.log(b.mime)

まとめ

MIMEタイプとGo、Node.jsで検出する方法をまとめました。