ホームページ  >  記事  >  バックエンド開発  >  PHP セキュリティ - ファイル アップロード攻撃

PHP セキュリティ - ファイル アップロード攻撃

黄舟
黄舟オリジナル
2017-02-22 09:26:092067ブラウズ



ファイルアップロード攻撃

場合によっては、標準のフォーム データに加えて、ユーザーがファイルをアップロードできるようにする必要もあります。ファイルはフォーム内の他のフォーム データとは異なる方法で送信されるため、特別なエンコード方法 multipart/form-data を指定する必要があります:

CODE:

<form action="upload.php" method="POST"
enctype="multipart/form-data">

通常のフォーム データとファイルの形式は特殊な形式であり、エンコード方法を指定することでブラウザが形式の要件に従って処理できるようになります。

ユーザーがファイルを選択してアップロードできるフォーム要素は非常にシンプルです:

<input type="file" name="attachment" />

さまざまなブラウザーでのこの要素の外観は異なります。従来、インターフェイスには標準のテキスト ボックスと参照ボタンが含まれており、ユーザーはファイルのパスを手動で直接入力したり、参照してファイルを選択したりできます。 Safariブラウザには参照ボタンしかありません。幸いなことに、それらの機能と動作は同じです。

ファイルアップロードメカニズムをよりわかりやすく説明するために、ユーザーが添付ファイルをアップロードできるようにする例を次に示します。 _FI LE_SIZE が伝えるブラウザでアップロードできる最大ファイル サイズを指定します。多くのクライアント側の制限と同様、この制限も攻撃者によって簡単に回避されてしまいますが、正規のユーザーには指針を提供します。この制限は、サーバー上で行われた場合にのみ信頼できます。

PHP 構成変数のうち、upload_max_filesize は、アップロードできる最大ファイル サイズを制御します。同時に、ファイルはフォーム データを通じてアップロードされるため、post_max_size (POST フォームの最大送信データ サイズ) も制御できる可能性があります。 P 受信プログラム UPLOAD.PHP は、スーパーグローバル配列 $ _Files:

Code:

<form action="upload.php" method="POST"
enctype="multipart/form-data">
  

Please choose a file to upload:


の内容を表示します。アップロードプロセスを理解するために、author という名前を使用します。テスト用の txt ファイルの内容は次のとおりです:

CODE:

<?php
 
  header(&#39;Content-Type: text/plain&#39;);
  print_r($_FILES);
 
  ?>

ファイルを Upload.php プログラムにアップロードすると、参照できます。同様の出力が表示されます。ブラウザで次のようになります:

CODE:

  Chris Shiflett
  http://www.php.cn/

上記から、PHP がスーパーグローバル配列 $_FILES で実際に何を提供しているかがわかりますが、それはオリジナルですフォームデータの情報を与えることはできません。ブラウザが実際に何を送信しているかを知るために入力を識別する必要があるセキュリティを重視する開発者としては、次の HTTP リクエスト情報を確認する価値があります:

CODE:

 Array
  (
      [attachment] => Array
          (
              [name] => author.txt
              [type] => text/plain
              [tmp_name] => /tmp/phpShfltt
              [error] => 0
              [size] => 36
          )
 
  )

リクエストの形式を理解する必要はありませんが、ファイルと関連するメタデータを識別できる必要があります。ユーザーは名前と型のみを指定するため、tmp_name、error、size はすべて PHP によって提供されます。

PHPはアップロードされたファイルをファイルシステムの一時ファイル領域(この例では/tmp/phpShfltt)に保存するため、メモリへの保存や読み込みのために別の場所に移動するのが通常の操作です。 tmp_name をチェックして、それがアップロードされたファイル (/etc/passwd などではない) であることを確認しないと、理論的にリスクが生じます。攻撃者が tmp_name の値を変更できる既知の攻撃方法がないため、これは理論的リスクと呼ばれます。ただし、攻撃手段がないからといって、簡単なセキュリティ対策を講じる必要がないわけではありません。新しい攻撃は毎日出現しますが、簡単な手順 1 つでシステムを保護できます。

PHP は、これらの理論上のリスクを軽減するために、is_uploaded_file() と 2 つの便利な関数を提供します。 move_uploaded_file( )。 tmp_name のファイルがアップロードされたファイルであることを確認する必要がある場合は、 is_uploaded_file():

CODE:

POST /upload.php HTTP/1.1
  Host: example.org
  Content-Type: multipart/form-data;
boundary=----------12345
  Content-Length: 245
 
  ----------12345
  Content-Disposition: form-data; name="attachment";
filename="author.txt"
  Content-Type: text/plain
 
  Chris Shiflett
  http://www.php.cn/
 
  ----------12345
  Content-Disposition: form-data;
name="MAX_FILE_SIZE"
 
  1024
  ----------12345--

を使用できます。

如果你希望只把上传的文件移到一个固定位置,你可以使用move_uploaded_file( ):

CODE:

 

 <?php
 
  $old_filename =
$_FILES[&#39;attachment&#39;][&#39;tmp_name&#39;];
  $new_filename = &#39;/path/to/attachment.txt&#39;;
 
  if (move_uploaded_file($old_filename,
$new_filename))
  {
    /* $old_filename is an uploaded file, and the
move was successful. */
  }
 
  ?>


最后你可以用 filesize( ) 来校验文件的大小:

CODE:

 

 <?php
 
  $filename = $_FILES[&#39;attachment&#39;][&#39;tmp_name&#39;];
 
  if (is_uploaded_file($filename))
  {
    $size = filesize($filename);
  }
 
  ?>


这些安全措施的目的是加上一层额外的安全保护层。最佳的方法是永远尽可能少地去信任。 

以上就是PHP安全-文件上传攻击的内容,更多相关内容请关注PHP中文网(www.php.cn)!


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。