2021.05.08

【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による画像アップロード時のバリデーションについて紹介させていただきました。

当サイトではWordpressのカスタマイズ制作依頼を請け負っています。運営中のサイトで何かお困りのことがある方は、下記の記事を参照のうえ気軽にご相談ください。

どんな機能・要望でもOK!『Wordpressのカスタマイズ制作』はじめました。

こんにちは、webエンジニアのゾノ( @ozonosho )です。 このたびWordpressのカスタマイズ制作をはじめました。......

→この記事を読む
チャレンジを応援する無料オンラインコミュニティ運営中!

生きづらさを抱える人のチャレンジを応援する無料オンラインコミュニティ『Cree』をスタートしました。ただいま参加者100名突破!お互いの目標を共有したり、就労・就職のサポートするサービスを無料で提供しています。

オンラインコミュニティの詳細はこちら

ゾノについて

お仕事のご相談はこちら