7

Java から PHP へのストリーム アップロードを実行すると、入力変数が の制限を超えているという PHP エラーが表示されることがありますmax_input_vars

最初は、その理由がわかりませんでした。最初に説明させてください:

ファイルは、次のようなアプローチでアップロードされています。

// get file data from input stream
$putdata = fopen("php://input", "r");
$tmp = tmpfile();
filesize = stream_copy_to_stream ($putdata, $tmp);
fclose ($putdata);

// copy temp stream into destination stream
$target = fopen('myfile.dwg', "w");        
fseek($tmp, 0, SEEK_SET);
stream_copy_to_stream($tmp, $target);
fclose($target);
fclose ($tmp);

PHP がこのような警告を表示する理由を理解するために、送信されたデータのダンプを取りました。

file_put_contents ('input_vars.log', print_r ($_REQUEST, true));
file_put_contents ('php_input.log', file_get_contents ('php://input'));

ここで面白いのは、アップロードされているファイルが 1.8 メガバイトであるということです。結果のログは次のとおりです。

  • input_vars.log=> 5 メガバイト、90,000 行
  • php_input.log => 20 メガバイト、283,000 行

エラーメッセージが突然正当に見えるようになりました。にはバイトコードが含まれているphp_input.logだけですが、次のinput_vars.logようにフォーマットされています。

Array
(
    [filename] => 0018-101-001_67.dwg
    [versionId] => 11253
    [filetype] => dwg
    [‘á‹Úê-8øFj–sÙ/ghÔ÷JJÐWhvPV] => ...
    ....
)

最初の 3 つのキーは GET 経由で送信され、残りはすべてファイル データになります。の一致を検索してカウントすると=>、25,954 件の一致が得られます。REQUEST次に、 26,000 個のキーを保持していると仮定します。

さて、私の質問に移りましょう。max_input_vars値を数回上げましたが、現在は の値を保持しています30000。このセキュリティ設定を無視して、可能な限り高く設定する必要がありますか? 私の懸念は、REQUEST 配列が より大きい場合、PHP が REQUEST 配列からパーツを削除30000し、ファイルが破損することです。

この値を高く設定しすぎると、セキュリティ上の問題はありますか? ファイルを PHP にアップロードするより良い方法はありますか?

4

6 に答える 6

2

PHPがファイル本体を解析しないように、enable_post_data_readingディレクティブを「false」(または「Off」)に設定してみてください。

ところで、PHP 5.3.9を使用している場合は、max_input_varsの脆弱性にパッチを適用する必要があります。

于 2012-10-26T14:45:27.157 に答える
2

あなたがしたいのはPUT アップロードです。それを POST として扱うべきではありません。または - 少なくとも - Content-TypeHTTP ヘッダーをapplication/octet-stream

于 2012-10-27T15:12:01.757 に答える
1

「php.net」( PHP.NET - max_input_vars ) 自体では、この設定の値を増やしても問題はないと報告されていますが、これは「このディレクティブを使用すると、サービス拒否の可能性が軽減される」という形式です。ハッシュ衝突を利用した攻撃」.

この行き詰まりを解決するには、以下の関数を使用して、実行時に変数値を設定してみてください。

ini_set("max_input_vars", 30000);

私は最近、この問題と、呼び出しがリモートであり、ランタイムを構成するために与えられていない方法を経験したため、残念ながら値を増やす必要がありました。

今までは問題はありませんでしたが、アイデアは将来であり、コードを変更してデータを部分ごとに送信し、コードを言語の標準の現在の構成内に保ちます。

于 2012-10-26T14:30:18.920 に答える
0

Java でファイルをアップロードする方法は示していません。PHP は、通常の POST リクエストをフォームから送信されたかのように処理し、フォームからフィールドを解析しようとします。データがバイナリの場合は良くありません。HTML ファイルのアップロード フォームが行うことをエミュレートして、「マルチパート ポスト」を送信する方がよいでしょう ()。次に、フォームから受信するかのように、 PHP の標準ファイル アップロード処理機能を使用します。

于 2012-10-26T14:25:50.300 に答える
0

受け入れられた答えは有効ですが、オフにすることは、enable_post_data_reading自動入力をオフにすることも意味するという事実に注意する必要があります$_POST$_GETおよび$_REQUEST配列。これらの配列を広範囲に使用してenable_post_data_readingいるため、ファイルのアップロード専用の特定のファイルに限定することにしました。

<Files "UploadFile.php">
    php_value enable_post_data_reading Off
</Files>

私は ajax リクエストを使用してアップロードしているため、ユーザー定義のヘッダーを次のように設定できます。

oXhr.setRequestHeader("X-File-Name", I_sFileName);
oXhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

そうすることで、$_REQUESTまたはを使用する必要がなくなります。これは、次のよう$_POSTにして php で情報を取得するためです。

$fileName = $_SERVER['HTTP_X_FILE_NAME'];

于 2016-04-08T03:21:53.967 に答える
-1

php.iniのpost_max_size、upload_max_filesize、max_file_uploadsのサイズを大きくしてみてください

于 2012-10-31T10:01:43.020 に答える