24

画像を正常にアップロードできますが、タイプを image/jpg、image/gif から application/msword および application/pdf に変更すると機能しません。これが私のコードです。画像に対してはまったく同じコードが機能しますが、ドキュメントや PDF をアップロードすると、「無効なファイル」が出力されます。何が起きてる?私のファイルは約 30kb しかなく、こちらのファイル サイズ制限を十分に下回っています。

$allowedExts = array("pdf", "doc", "docx"); 
$extension = end(explode(".", $_FILES["file"]["name"]));

if ( ( ($_FILES["file"]["type"] == "application/msword") || ($_FILES["file"]["type"] == "text/pdf") ) 
&& ($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))
{      
 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); 
}
else
{
echo "Invalid file."
}
4

7 に答える 7

40

['type']アップロードを検証するためにパラメータを使用しないでください。このフィールドはユーザーが提供するものであり、簡単に偽造できるため、あらゆる種類のファイルをアップロードできます。同じことが['name']パラメータにも当てはまります-それはユーザーによって提供されたファイルの名前です。偽造するのも簡単なので、ユーザーはそれを送信nastyvirus.exeおよび呼び出しますcutekittens.jpg

アップロードを検証するための適切な方法は、たとえばfileinfoを介したサーバー側のmimeタイプの決定を使用することと、適切なアップロード成功チェックを行うことです。

if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
    die("Upload failed with error " . $_FILES['file']['error']);
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $_FILES['file']['tmp_name']);
$ok = false;
switch ($mime) {
   case 'image/jpeg':
   case 'application/pdf'
   case etc....
        $ok = true;
   default:
       die("Unknown/not permitted file type");
}
move_uploaded_file(...);

また、move_uploaded_filesの最終的な宛先の一部としてユーザー提供のファイル名を使用しています。パスデータをそのファイル名に埋め込むことも簡単で、それを盲目的に使用します。つまり、悪意のあるリモートユーザーは、パスを知っているサーバー上の任意のファイルに落書きしたり、新しいファイルを作成したりする可能性があります。

于 2012-07-22T15:17:17.000 に答える
9

コードに正しい MIME タイプを追加してください - 少なくとも次のもの:

.jpeg -> image/jpeg
.gif  -> image/gif
.png  -> image/png

MIME タイプのリストは、ここにあります。

さらに、コードのロジックを簡素化し、エラー番号を報告して、最初のレベルのサポートが問題を追跡できるようにします。

$allowedExts = array(
  "pdf", 
  "doc", 
  "docx"
); 

$allowedMimeTypes = array( 
  'application/msword',
  'text/pdf',
  'image/gif',
  'image/jpeg',
  'image/png'
);

$extension = end(explode(".", $_FILES["file"]["name"]));

if ( 20000 < $_FILES["file"]["size"]  ) {
  die( 'Please provide a smaller file [E/1].' );
}

if ( ! ( in_array($extension, $allowedExts ) ) ) {
  die('Please provide another file type [E/2].');
}

if ( in_array( $_FILES["file"]["type"], $allowedMimeTypes ) ) 
{      
 move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]); 
}
else
{
die('Please provide another file type [E/3].');
}
于 2012-07-22T15:09:01.040 に答える
2

条件の 1 つが失敗しています。ファイルの mime-type の値を確認してください。
text/pdf ではなく、application/pdf を使用してみてください。PDF ファイルの適切な MIME メディア タイプを参照してください。

于 2012-07-22T15:05:02.990 に答える
1

使用できます

$_FILES['filename']['error'];

いずれかのタイプのエラーが発生した場合は、「エラー」を返します。それ以外の場合は 1,2,3,4 または 1 を返します。

1 : ファイルサイズが制限を超えている場合 .... グーグルで他のオプションを見つけることができます

于 2016-01-06T19:11:37.483 に答える
-1

application/msword と application/vnd.ms-excel の場合、サイズ制限を削除すると、次のようになります。

($_FILES["file"]["size"] < 20000)

...うまくいきました。

于 2014-07-22T18:56:31.557 に答える