web-dev-qa-db-ja.com

PHPファイルアップロードの検証

私はPHP初心者で、現在「ファイルアップロードの検証」の部分を学んでいます。

次のコードを含むtest.phpページを作成しました。

var_dump(@$_FILES['file']['type']);

まず、画像「img.gif」をアップロードすると、次のように返されました。

string 'image/gif' (length=9)

次に、画像の拡張子を ".jpg"に変更すると、次のように返されます。

string 'image/jpeg' (length=10)

そのため、$ _ FILES ["file"] ["type"]はアップロードされたファイル拡張子のみを返すことに気付きましたが、実際にはどのファイルであるかを確認していません。

このページには http://www.w3schools.com/php/php_file_upload.asp 、コードがあります:

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

上記のコードがファイル拡張子を2回チェックするのはなぜですか?上記のコードからいくつかを削除しました。これが私の新しいコードです。

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))

私のコードは正しいですか?または、アップロードファイルが画像であることを検証するためのより良い方法はありますか?

ありがとう!

8
nut

ファイルのtmp_name *を getimagesize に渡す必要があります。これにより、イメージのサイズとタイプ(イメージの場合)が得られます。渡された引数がファイルであるが画像ではない場合、falseが返され、検証が可能になります。

編集:画像検証の唯一の信頼できる方法は、GdまたはImagickを使用してそれをコピーすることです- getimagesizeは簡単にハッキングできます

*:つまり、アップロード後に作成された一時ファイルです。

例えば:

if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $file = $_FILES['file']['tmp_name'];
    if (file_exists($file))
    {
        $imagesizedata = getimagesize($file);
        if ($imagesizedata === FALSE)
        {
            //not image
        }
        else
        {
            //image
            //use $imagesizedata to get extra info
        }
    }
    else
    {
        //not file
    }
}

このコードは、一般的な目的で file_exists を使用しています。ファイルがアップロードされていない場合は、$_FILES['file']['size'] = 0$_FILES['file']['tmp_name'] = ''および$_FILES['file']['error'] = 4is_読み取り可能 も参照してください。エラー値については、 php.netファイルアップロードエラーの説明 を参照してください。

15
Theraot
$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

ファイルの拡張子と「ファイルタイプ」が異なる可能性があるため、誰かが.png拡張子の実行可能ファイルをアップロードできないため、これは2回チェックされます。

変更されたコードでは、変更された拡張子を持つ別のタイプのファイルをアップロードすることが可能です。 '.png'拡張子の付いたWord文書をアップロードできるように。

新しいコードは拡張子をチェックしているだけで、ダブルチェックはありません。

3
Maulik Vora

新しいコードは、ファイルの拡張子とファイルのサイズのみをチェックします。ファイルの種類はチェックしません。

ファイルタイプもチェックするため、古いコードを使用することを強くお勧めします。

0
Yogesh Suthar