2

すべての $_POST 変数を収集し、それらを動的に名前が付けられた変数に割り当てるループを作成することを考えています。このようなもの (テストされていません)

 for($i; $i <= $_POST[].length; $i++){
  ${$_POST[i]} = $_POST[i]
  }

しかし、私はこのようなもののセキュリティについて疑問に思っています。これにより、ページに送信される投稿データのすべてのビットに対して、システム内に変数が作成されます。私が書いたスクリプトがそれを参照していなくても、その変数は損害を与える可能性がありますか? これは私が完全に避けるべきタイプのものですか?かなりの数の変数を送信するページがいくつかあり、このようなスクリプトを使用すると大量の書き込みが妨げられますが、十分に安全ですか?

4

7 に答える 7

4

はい、セキュリティリスクの可能性があります。

$is_admin誰かに管理者権限を与える変数がコードの前半で定義されているとします。誰かがそのページに投稿した場合

$_POST['is_admin'] = true;

それから$is_admin今は本当です。良くない。

を使用して何が問題になってい$_POSTますか?

于 2012-07-19T05:44:07.603 に答える
2

これは、セキュリティと保守性にとって非常に悪い考えです。簡単な例 理由...

<?php

if (someRandomSessionCheck()) {
    $isAdminUser = true;
}


if ($isAdminUser) {
    // give access to everything
}

?>

誰かが変数「isAdminUser=1」でページに投稿でき、すべてにアクセスできます。

それが悪い考えであるもう 1 つの理由は、変数が作成された場所をスクリプトから明確に確認できないことです。これにより、スクリプトの保守性が低下します。スクリプトを実行したいが、代わりに POST ではなく別の場所からデータを取得する必要がある場合はどうすればよいでしょうか?

于 2012-07-19T05:44:35.867 に答える
2

はい、セキュリティ上の懸念/問題が発生する可能性があります。たとえば、データベース、構成値など、既に設定されているローカル変数を上書きする可能性があります。

したがって、次のようなことは避ける必要があります。

$yourImportantVar = 'Something relies on this';

//User POSTS yourImportantVar=overwritten
foreach ($_POST as $key => $value) {
    $$key = $value; 
}
echo $yourImportantVar; //overwritten 

しかし、コードのチャンクを保存するためにループを実装したい場合は、ループして $_POST から値を抽出する許可された配列を作成できます。

foreach (array(
    'name',
    'address',
    'somethingelse',
    'ect'
) as $key) {
    $$key = isset($_POST[$key]) ? $_POST[$key] : null;
}
于 2012-07-19T05:50:35.290 に答える
1

現時点で私が考えることができる唯一の問題は、それがスコープ内の既存の変数を上書きするときです。何をするかによっては、これは非常に危険な場合があります。変数がHTTPリクエストを実行しているURLであると考えてください。さらに悪いことに、コードの重要な部分にアクセスするフラグ変数。

HTTPリクエストについて説明する例を投稿します。

<?php
    $url = "http://safe/url/to/POSTto";
    $var = array("url" => "http://www.mysite.com/url"); //assume this is $_POST
    foreach($var as $key => $value){
        ${$key} = $value;
    }

    //now upon the HttpRequest, your site can receive the (critical) data which was actually meant for the safe site.
?>

編集:@Galenは私が話していたフラグ変数について投稿したので、問題を強調するために例を投稿する必要はないかもしれません。

于 2012-07-19T05:46:14.900 に答える
1

PHP には、(大まかに用語を使用して) と呼ばれる機能がありましたregister_globals。その後、非推奨 (PHP 5.3) および削除 (PHP 5.4) されましたが、探している機能を反映しています。extract()これは、現在のスコープ内の変数にキーの名前と一致する配列値の値を設定 する PHP 関数と同じことを実行します。これは間違いなくセキュリティ リスクです。認証の不十分なチェックの例を考えてみましょう。

if($is_logged_in) {
    // Allow execution of destructive actions
}

この機能が有効になっている (または模倣した) 場合、悪意のあるユーザーは変数を設定し$is_logged_inてログイン画面をバイパスできます。入力の節約について心配する必要はありません。ファイルの先頭に次のようなコード ブロックをコピーして貼り付ける必要がある場合:

$something = $_POST['something'];
$another   = $_POST['another'];
$stuff     = $_POST['stuff'];
//etc.

はるかに安全であるだけでなくregister_globals、宣言されていない変数が使用され始めたときに (期待していない) 開発者を戸惑わせることもありません。また、PHP がそれを削除したという事実と、その使用に反対する多く議論 があるという事実は、十分な証拠となるはずです。

于 2012-07-19T05:53:29.653 に答える
0
 <?php

/* Suppose that $var_array is an array returned from
  wddx_deserialize */

 $size = "large";
 $var_array = array("color" => "blue",
               "size"  => "medium",
               "shape" => "sphere");
 extract($var_array, EXTR_PREFIX_SAME, "wddx");

 echo "$color, $size, $shape, $wddx_size\n";

  ?>

これを確認してください。ループを使用して行うことと同じこと。あなたを助けるかもしれません

于 2012-07-19T05:43:11.697 に答える
0

基本的にextract($_POST, EXTR_OVERWRITE)、既存の変数を上書きする実装を行っています。マニュアルは、あなたが行う方法で使用するようにすでに警告してextractいます:

extract()ユーザー入力 (つまり$_GET$_FILESなど)のような信頼できないデータには使用しないでください。たとえば、一時的にregister_globalsに依存する古いコードを実行する場合は、次のような上書きされないextract_type値のいずれかを使用するようEXTR_SKIPにしてください。 php.ini.

$_SESSIONこれにより、 、$_SERVER、およびのように実際には直接変更できないものを含む、重要で機密性の高い変数が上書きされる可能性があります$GLOBALS

POST /foo.php HTTP/1.1
Content-Type: application/x-www-urlencoded

_SESSION[user]=admin

これは と同じ効果があり$_SESSION = array('user'=>'admin')ます。

于 2012-07-19T07:09:18.610 に答える