pngとjpegしか、アップさせないサーバ側のコードを書いてみました。
要は画像の拡張子と中身のチェック、トーコンチェック、画像を2変換して、リスクのあるコードを実行させないような処理。
Laravelを使ってるので、書き方が普通のPHPと少し違います。
//Fileの中身をチェックし、画像ファイルかどうかを検証する
if(count($_FILES) != 0)
{
$file = request()->file('files')[0];
$allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG);
$detectedType = exif_imagetype($file);//普通のphp:exif_imagetype($_FILES['files']['tmp_name'][0]);
$originalFileName = $file->getClientOriginalName();//普通のPHPだと:pathinfo($_FILES['files']['name'][0], PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();//普通のPHPだと:$array = explode('.', $_FILES['files']['name'][0]);$extension = end($array);
if(!in_array($detectedType, $allowedTypes)) {
header('Content-Type: application/json; charset=UTF-8');
die(json_encode(array('message' => 'FormatErr')));
} else {
$regexPNG = '/png$/i';
$regexJPG = '/jpe?g$/i';
if((preg_match($regexPNG,$extension) && ($detectedType != 3)) || (preg_match($regexJPG,$extension) && ($detectedType != 2)))
{
header('Content-Type: application/json; charset=UTF-8');
die(json_encode(array('message' => 'ExtensionErr')));
}
if (!preg_match('/\.(jpe?g|png)$/i', $_FILES['files']['name'][0])) {
header('Content-Type: application/json; charset=UTF-8');
die(json_encode(array('message' => 'ExtensionErr')));
}
// 画像アップロード・表示用のストレージ
$imageFolder = ("abcde/");
//重複しないファイル名を生成する
$filename = $なんちゃらid . '_' . count($this->storage->files($imageFolder)) . '.' . $extension;//「storage」のはLaravelの書き方
if (count(token_get_all($file)) >= 2) {
header('Content-Type: application/json; charset=UTF-8');
die(json_encode(array('message' => 'ExtensionErr')));
}
//画像を二変換する 参考記事:https://blog.ohgaki.net/c_ra_a_a_ia_ca_la_lphpa_sa_fa_a_a_a_effa
if (preg_match($regexPNG,$extension)) {
//一回目
$imageTmp1 = imagecreatefrompng($file);
ob_start();
imagejpeg($imageTmp1);
$outputImage1 = ob_get_clean();
imagedestroy($imageTmp1);
//二回目
$imageTmp2 = imagecreatefromstring($outputImage1);
ob_start();
imagepng($imageTmp2);
$outputFinal = ob_get_clean();
\Storage::put($imageFolder. $filename, $outputFinal);//Laravelの書き方
//imagepng($imageTmp2, imageFolder. $filename, 0);//普通のPHPの書き方、直接ファイル出力したいところに置く。
imagedestroy($imageTmp2);
} else if (preg_match($regexJPG,$extension)) {//省略
}
//正常アップロード
return response()->json(array());//普通のPHP:header('Content-Type: application/json; charset=UTF-8');echo json_encode(array());
}
}