(148) 画像ファイルのアップロード処理のセキュリティ対策

投稿者: | 2023年12月24日

94 views

1. やりたいこと

共用レンタルサーバーで運用中の自作ホームページがある。
ここに画像ファイルのアップロード機能を実装したい。

この時、以下の懸念点がある。

懸念点1: 画像ファイル以外のファイルがアップロードされてしまわないか?
  → CGIスクリプトファイルなどがアップロードされれば、好き放題に荒らされてしまう…

懸念点2: 超巨大な画像ファイルがアップロードされないか?
  → サーバー負荷増大でアカウントを BANされてしまうかも…

これらの懸念点を払しょくするための実装及び環境設定をしておきたい。

2. やってみる

懸念点1:画像ファイル以外のファイルがアップロードされてしまわないか?

対策1:画像受信プログラム側で、拡張子、MIMEタイプ、画像情報を検査する。

// アップロードされたファイルが、画像ファイルであることを確認する。
// $sgv_file : $_FILES{'xxxxx'] を入力する。
function isValidImageFile( $sgv_file ){
  $ret = false;
  $allowedExts = ['jpg', 'jpeg', 'png', 'gif', 'tiff', 'tif'];
  $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/tiff'];

  // check 1 : 拡張子を検査
  $ext = pathinfo($sgv_file['name'], PATHINFO_EXTENSION);   // ファイル名文字列から拡張子を取得
  if(false === in_array(strtolower($ext), $allowedExts)){   // 受け入れ可能な拡張子?
    goto tagEND;
  }

  // check 2 : MIMEタイプを検査
  $fileMimeType = mime_content_type($sgv_file['tmp_name']); // UploadされたファイルのMIMEタイプを取得
  if(false === in_array($fileMimeType, $allowedMimeTypes)){ // 受け入れ可能なMIMEタイプ?
    goto tagEND;
  }

  // check 3 : 画像ファイルヘッダを検査
  if (false === getimagesize($sgv_file['tmp_name'])) {
    goto tagEND;
  }

  // 画像ファイルであると確認した。
  $ret = true;

tagEND:
  return $ret;
}

対策2:画像保存ディレクトリではCGI実行を禁止する。

Webサーバ(ここでは Apache2.4)の設定ファイルに、CGIファイルへアクセス禁止を設定しておく。
このファイルを画像保存ディレクトリに設置する。

.htaccess

<FilesMatch "\.(php|cgi|py|pl)$">
    Require all denied
</FilesMatch>

Apacheのバージョンを知りたければ、以下のコマンドで確認できる。

$ apache2 -v
$ httpd -v

懸念点2:超巨大な画像ファイルがアップロードされないか?

PHPの設定ファイルに以下を設定しておく。
upload_max_filesize : アップロード可能なファイルサイズの上限
post_max_size : POSTメッセージで送信可能なデータサイズの上限

このファイルを自作ホームページのTopディレクトリに設置する。

.user.ini

upload_max_filesize = 2M
post_max_size = 8M

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)