【php】【セキュリティ対策】getimagesize関数で防げない不正画像アップロード対策について

こんにちは、webエンジニアのゾノ( @ozonosho )です。

今回はphpによる画像アップロード時のバリデーションについてです。

アップロード機能は自社サーバー内にユーザーの所有するファイルをアップロードするため、とりわけセキュリティリスクの高い機能になります。

通常、画像アップロードにおいては下記のようなバリデーションをおこないます。

画像アップロードのバリデーション
  • 画像形式チェック(拡張子やMIMEタイプに問題ないか)
  • 容量チェック
  • 権限チェック(適切な権限を持つユーザーかどうか)

しかし上記のバリデーションでは防げないケースがあります。

それは「スクリプトを埋め込んだテキストファイルの拡張子を.pngや.jpgにしてアップロードされる」というケースです。

この場合、拡張子チェックで弾けないのはもちろん、MIMEタイプもimage/gifとして認識されてしまい、exif_imagetype関数やmime_content_type関数やgetimagesize関数を利用してもエラー判定できません。

ちなみに、ググって出てくる記事のほとんどは上記関数を利用したバリデーションまでしか記載されていません。

ではこういったケースでどうすれば良いかというと、下記2つの方法があります。
(他にもあるかもしれません)

本当に画像ファイルなのか判定する方法
  1. アップロードファイルのマジックナンバーを見る
  2. アップロードファイルの中身のバイナリデータから画像を生成できるか確かめる

①のマジックナンバーとはファイルごとのフォーマットを識別するための特定の数値のことで、アップロードファイル内にこの数値が含まれているかどうかでバリデーションする方法です。

ただ、、、テストした限り①だと完璧に弾くことはできなかったので僕は②を採用しました。

②はアップロードされたファイルの中身を読み込んで画像として正しく生成できるかチェックする方法です。

phpの「imagecreatefromstring」という関数を利用することで実装できます。

※imagecreatefromstring関数の詳細はphp.net参照

この方法だと画像のフリをした怪しいファイルをほぼ弾くことができるので、画像アップロード機能を実装する際にはぜひ利用してみてください。

おわりに

以上、今回の記事ではphpによる画像アップロード時のバリデーションについて紹介させていただきました。

つくりばのことが気になりましたか?

つくりばは、ココトモ・未来地図を自社で10年以上運営してきた知見をもとに、相談・コミュニティの開発と運営を支援しています。いきなりのご相談でなくて大丈夫です。まずは私たちの実績や考え方をご覧ください。

つくりばについて知る

← WordPressの一覧へ戻る

Webサービスの課題を、まずは無料相談で整理しませんか。

既存サービスの改善、新規立ち上げ、運用サポート、予算内での優先順位づけなど、今の状況に合わせてじっくりお話を伺います。まだ形になっていない段階のご相談も大丈夫です。

  • videocamオンライン対応
  • forum課題整理だけでも歓迎
  • payments概算費用の目安がわかる
無料相談を申し込む