web-dev-qa-db-ja.com

$ _REQUEST []の使用の何が問題になっていますか?

ここで、$_REQUEST変数を使用しないことを言っている多くの投稿を見てきました。私は通常そうしませんが、時には便利です。どうしたんだ?

115
sprugman

PHP Internals に関するニュースグループの投稿を掘り下げてみて、このトピックに関する興味深い議論を見つけました。最初のスレッドは何か他のものに関するものでしたが、PHPの世界のセキュリティ専門家(theでない場合)のStefan Esserによる発言は、議論をいくつかの投稿に$ _REQUESTを使用することのセキュリティへの影響。

引用 Stefan Esser on PHP Internals

$ _REQUESTは、PHPの最大の設計上の弱点の1つです。 $ _REQUESTを使用するすべてのアプリケーションは、遅延クロスサイトリクエストフォージェリの問題に対して最も脆弱です。 (これは基本的に、たとえば(年齢)という名前のCookieが存在する場合、常にGET/POSTコンテンツを上書きするため、不要なリクエストが実行されることを意味します)

そして 同じスレッドへの後での返信

誰かがGET、POSTを偽造できるということではありません。 COOKIE変数。これは、COOKIEがREQUESTのGETおよびPOSTデータを上書きするという事実です。

したがって、ブラウザにCookieを感染させる可能性があります。 action = logoutを指定すると、REQUEST [action]は永久にログアウトするため(Cookieを手動で削除するまで)、アプリケーションを使用できなくなります。

そして、あなたをCOOKIEに感染させるのはとても簡単です...
a)サブドメイン上の任意のアプリケーションでXSS vulnを使用できます
b)単一のドメインを所有しているときに* .co.ukまたは* .co.krのCookieを設定しようとしたことがありますか?
c)その他のクロスドメイン...

そして、これが問題ではないと信じているなら、f.e。を設定する簡単な可能性があることを伝えることができます。いくつかのPHPバージョンがホワイトページを返すだけの* .co.kr Cookie。想像してみてください。*。co.krのすべてのPHPページを削除するための単一のCookie

そして、+。PHP.ESSID =illegalという変数の* .co.krに対して有効なCookieに不正なセッションIDを設定することにより、PHPアプリケーションごとにDOSを実行できます。韓国ではPHPセッションを使用しています...

議論はさらにいくつかの投稿のために続き、読むのは興味深いです。


ご覧のとおり、$ _ REQUESTの主な問題は、$ _ GETおよび$ _POSTからのデータだけでなく、$ _ COOKIEからのデータもあることです。リストの他の何人かは、$ _ REQUESTが満たされる順序を変更することを提案しました。最初に$ _COOKIEを入力しますが、 これにより、セッション処理など、他の多くの潜在的な問題が発生する可能性があります

ただし、$ _ REQUESTグローバルから$ _COOKIESを完全に省略して、他の配列によって上書きされないようにすることができます(実際、 PHPマニュアルのように、その標準コンテンツの任意の組み合わせに制限できますvariable_orderini setting は次のことを示しています。

variable_order EGPCS(Environment、Get、Post、Cookie、およびServer)変数解析の順序を設定します。たとえば、variables_orderが「SP」に設定されている場合、PHPはスーパーグローバル$ _SERVERおよび$ _POSTを作成しますが、$ _ ENV、$ _ GET、および$ _COOKIEは作成しません。 「」に設定すると、スーパーグローバルは設定されません。

ただし、PHPでは環境、取得、投稿、Cookie、およびサーバーに独自のグローバルでアクセスでき、攻撃ベクトルが1つ少ないため、$ _ REQUESTをまったく使用しないことを検討することもできます。このデータをサニタイズする必要がありますが、心配する必要はもう1つありません。


どうして$ _REQUESTが存在するのか、なぜ削除されないのか疑問に思うかもしれません。これはPHP Internalsでも同様に尋ねられました。 Rasmus Lerdorfについて なぜ$ _REQUESTが存在するのか? on PHP Internals

このようなものを削除すればするほど、人々がPHPの新しい、より速く、より安全なバージョンにすばやく移行することは難しくなります。それは、いくつかの「ugい」レガシー機能よりも、誰にとってもはるかにフラストレーションを引き起こします。適切な技術的理由、パフォーマンス、またはセキュリティがある場合は、それを厳しく調べる必要があります。この場合、見なければならないのは、$ _ REQUESTを削除するかどうかではなく、Cookieデータを削除するかどうかです。私自身のものも含めて、多くの構成がすでにそれを行っており、$ _ REQUESTにCookieを含めない強力な有効なセキュリティ上の理由があります。ほとんどの人は$ _REQUESTを使用してGETまたはPOSTを意味しますが、Cookieが含まれている可能性があることや、そのような悪者がCookieインジェクショントリックを実行して単純なアプリケーションを破壊する可能性があることを認識していません。

とにかく、光を当てることを願っています。

72
Gordon

$_REQUESTは、あらゆる種類のリクエストを指します(GET、POSTなど)。これは便利な場合もありますが、通常は正確なメソッド($ _GET、$ _ POSTなど)を指定することをお勧めします。

10
Luca Matteis

GETリクエストはべき等である必要があり、POSTリクエストは一般にそうではありません。つまり、$_GET$_POSTのデータは一般に異なる方法で使用する必要があります。

アプリケーションが$_REQUESTからのデータを使用している場合、GETおよびPOSTリクエストの両方で同じ動作をします。これはGETのべき等性に違反します。

8
Ben James

_$_REQUEST_は一般に、SQLで宣言されるのではなく、アプリケーションコードで単純から中程度の複雑さのデータ変換が実行されるのと同じ理由で有害であると考えられています。

そのため、_$_REQUEST_をどこでも使用する傾向がある場合、GETを使用してPOSTでできることは何でもできます。つまり、ユーザーが自分の電子メールにログインする(悪意のある)サイトで_<img>_タグを設定する-商品を静かに購入するためのコマースモジュール、または危険なアクションや機密情報の公開(おそらく私にとって)につながるリンクをクリックさせることができます。

ただし、これは初心者、または少なくとも経験の浅い人のためです。PHPプログラマーが簡単なミスを犯しています。まず、どのタイプのデータが適切かを知ってください。たとえば、私はURLEncoding、XML、またはJSONで応答を返すことができます。アプリケーションは、HTTP_ACCEPTヘッダーを確認して応答をフォーマットする方法を決定しますが、formatパラメーターを送信することで具体的に応答に変換できます。

Formatパラメーターの内容を確認するとき、多くの要因に応じて、クエリ文字列またはpostdataを介して送信できます。少なくとも、呼び出し側アプリケーションが要求に「&format = json」を混在させたいかどうかです。この場合、_$_REQUEST_は非常に便利です。次のように入力する必要がなくなるからです。

_$format = isset($_POST['format']) ? $_POST['format'] 
    : (isset($_GET['format']) ? $_GET['format'] : null);
_

これ以上詳しく説明するつもりはありませんが、_$_REQUEST_の使用は本質的に危険であるため、思いとどまらないと言うだけで十分です。これらの意味を理解しているかどうかにかかわらず、そうではありません-この問題を引き起こすのは、貧しい、怠zyな、または経験の浅いプログラマーの貧しい、怠laな、または知識のない決定です。

_$_REQUEST_を安全に使用する方法


  1. データを知る:取得するデータの種類についてある程度の期待が必要なので、それに応じてサニタイズしてください。データベースのデータ? addslashes()または*_escape_string()。ユーザーに表示しますか? htmlentities()またはhtmlspecialchars()。数値データが必要ですか? is_numeric()またはctype_digit()。実際、 filter_input() および関連する関数は、データのチェックとサニタイズのみを行うように設計されています。常にこれらのツールを使用してください。
  2. ユーザー指定のスーパーグローバルデータに直接アクセスしないでください。常にデータをサニタイズする習慣をつけ、データを_$post_clean_だけであってもクリーンな変数に移動します。または、スーパーグローバルで直接クリーンアップすることもできますが、別の変数を使用することを推奨する理由は、そうするとコードの脆弱性を簡単に見つけることができるためです。anythingサニタイズされた同等物ではなく、スーパーグローバルを直接指すことは危険なエラーと見なされます。
  3. データの送信元を確認します。上記の例を参照して、GETまたはPOSTを介して応答形式変数を送信できるようにすることは完全に合理的です。 。また、どちらの方法でも「アクション」変数を送信できます。ただし、アクション自体には、どのHTTP動詞が受け入れられるかについて非常に特定の要件があります。たとえば、サービスが使用するデータを変更する関数は、POSTを介してのみ送信できます。特定のタイプの非特権データまたは低特権データ(動的に生成されたマップイメージなど)の要求は、いずれかの方法からの要求に応じて処理できます。

結論として、この単純なルールを覚えておいてください。

セキュリティIS何をするか、人々!

編集:

I強くbobinceのアドバイスを推奨します:可能であれば、php.iniの_request_order_パラメーターを「GP」に設定します。つまり、Cookieコンポーネントはありません。 Cookieデータがクエリ文字列またはポストデータに匹敵するものと見なされることはほとんどないため、98%以上のケースではこれに関する合理的な推論はほとんどありません。

P.S.、逸話!

_$_REQUEST_を、スーパーグローバルな方法でアクセス可能なデータを単純に保存する場所と考えているプログラマーを知っていました。重要なユーザー名とパスワード、ファイルへのパス、名前を付けて、_$_REQUEST_に保存しました。私はその変数がどのように振る舞うかを彼に言ったとき、彼は少し驚いた(コミカルではないが、残念ながら)。言うまでもなく、その慣行は廃止されました。

8
Dereleased

あいまいです。 本当にポスト、取得、およびCookieデータを運ぶので、データがどのようにあなたに届いたかを知りません。 need配信方法を知ったり制限したりしない限り、必ずしも悪いことだとは思わない。

7
Sampson

私は実際にそれを使うのが好きです。 GETまたはPOSTを使用する柔軟性が得られます。これは、ほとんどの時間データがPOSTされる検索フォームのようなものに役立ちますが、特定のリンクへのリンクが必要な場合があります検索するので、代わりにGETパラメーターを使用できます。

また、他の多くの言語(ASP.NETなど)を見ると、GET変数とPOST変数はまったく区別されません。

[〜#〜] eta [〜#〜]

REQUESTを使用してCOOKIE値を取得したことはありませんが、この投稿に関するコメントでKyle Buttが素晴らしい点を示していると思います。 COOKIE値を取得するためにREQUESTを使用することはお勧めできません。もしそうすれば、クロスサイトリクエストフォージェリの本当の可能性があると彼は思う。

また、REQUESTにロードされるものの順序は、php.iniの構成パラメーター(variables_orderおよびrequest_order)によって制御されます。したがって、POSTとGETの両方を介して渡される同じ変数がある場合、実際にREQUESTに入力されるのはそれらのini設定に依存します。特定の順序と設定は、予想とは異なる構成になっています。

3
Eric Petroelje

$_REQUESTを使用するのは、GETを使用する場合のみです。

  • これを使用してPOST値をロードすると、クロスサイトリクエストフォージェリのリスクがあります
  • これを使用してCookie値をロードすると、クロスサイトリクエストフォージェリのリスクが再び発生します。

GETを使用しても、$_GET$_REQUESTよりも入力が短くなります;)

2

POSTを使用するタイミング、GETを使用するタイミング、Cookieを使用するタイミングを理解することが重要です。 $ _REQUESTを使用すると、探している値はそれらのいずれかから得られた可能性があります。 POSTまたはGETまたはCOOKIEから値を取得する場合、コードを読んでいる人が$ _REQUESTの代わりに特定の変数を使用する方が有益です。

他の誰かが、すべてのPOSTまたはCookieがGETによってオーバーライドされることを望まないことも指摘しました。たとえば、すべてに異なるサイト間ルールがあるためです。たとえば、$ _ REQUESTの使用中にajaxデータを返す場合、クロスサイトスクリプト攻撃に。

2
Kyle Butt

ダレンクック: "php 5.3以降、デフォルトのphp.iniではGETとPOSTデータは$_REQUESTを参照してください。 php.net/request_order Cookieデータが$_REQUESTにあると予期していて、なぜ機能しないのか疑問に思ったときに、この後方互換性の問題につまずいただけです!」

わあ...PHP 5.3へのアップグレードのために、スクリプトの一部が機能しなくなりました。同じことをしました事柄:$_REQUEST変数を使用するときにCookieが設定されると仮定します。

$_COOKIE["Cookie_name"]...を使用してCookie値を個別に呼び出すようになりました.

0
Arjan202

$_REQUESTに問題はないと思いますが、3つのソース(GPC)からの変数のコレクションであるため、使用する場合は注意する必要があります。

古いプログラムを新しいphpバージョンと互換性を持たせるために$_REQUESTがまだ利用できると思いますが、新しいプロジェクト(新しいライブラリを含む)を開始する場合、プログラムをより明確にするために$_REQUESTを使用すべきではないと思います。 $_REQUESTには$_REQUESTのコピーが含まれているため、$_POSTの使用を削除し、ラッパー関数に置き換えてプログラムを軽量化することを検討する必要があります。

// delete $_REQUEST when program execute, the program would be lighter 
// when large text submitted
unset($_REQUEST);

// wrapper function to get request var
function GetRequest($key, $default = null, $source = '') 
{
  if ($source == 'get') {
    if (isset($_GET[$key])) { 
      return $_GET[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'post') {
    if (isset($_POST[$key])) { 
      return $_POST[$key]; 
    } else { 
      return $default; 
    }
  } else if ($source == 'cookie') {
    if (isset($_COOKIE[$key])) { 
      return $_COOKIE[$key]; 
    } else { 
      return $default; 
    }
  } else {
    // no source specified, then find in GPC
    if (isset($_GET[$key])) {
      return $_GET[$key];     
    } else if (isset($_POST[$key])) {
      return $_POST[$key]; 
    } else if (isset($_COOKIE[$key])) {
      return $_COOKIE[$key]; 
    } else {
      return $default; 
    } 
  }
}
0
user953985

現在のURLまたはホスト名を取得したい場合にのみ使用されるかもしれませんが、&記号を使用してパラメーターなどのURLからデータを実際に解析するには、おそらく良い考えではありません。一般に、あなたがやろうとしていることのあいまいな説明を使用したくありません。特定する必要がある場合、それが$ _REQUESTの悪いところです。具体的にする必要がない場合は、自由に使用してください。私は思うだろう。

0
Brian T Hannan

必要なデータがわかっている場合は、明示的に要求する必要があります。 IMO、GET、およびPOSTは2種類の動物であり、投稿データとクエリ文字列を混在させる必要がある理由を考えることはできません。誰かが持っているなら、私は興味があります。

スクリプトが同じ方法でGETまたはPOSTに応答する可能性がある場合、$ _ REQUESTを使用すると便利です。ただし、これは非常にまれなケースであり、ほとんどの場合、2つの別個の概念を処理する2つの別個の関数、または少なくともメソッドをチェックして正しい変数を選択することが望ましいと主張します。通常、プログラムフローは、変数がどこから来たのかを相互参照する必要がない場合、はるかに簡単に追跡できます。 6か月以内にコードを保守しなければならない人に親切にしてください。それはあなたかもしれません。

CookieおよびREQUEST変数の環境変数(GLOBALで開始しないでください)によって引き起こされるセキュリティ問題とWTFに加えて、PHPが他のメソッドをネイティブにサポートし始めた場合、今後何が起こるか考えてくださいPUTおよびDELETEとして。これらがREQUESTスーパーグローバルにマージされることはほとんどありませんが、variable_order設定のonオプションとして含めることができます。そのため、特にサードパーティのサーバーにコードがデプロイされている場合、REQUESTが何を保持し、何を優先しているのかはまったくわかりません。

POSTはGETより安全ですか?あんまり。アプリケーションが攻撃を受けたときにどのように悪用されているかをログで簡単に確認できるため、実用的な場合はGETを使用することをお勧めします。 POSTは、クモが一般的に従わず、CMSにログインしたときに予測フェッチメカニズムがすべてのコンテンツを削除しないため、ドメイン状態に影響する操作に適しています。ただし、質問はGETとPOSTのメリットに関するものではなく、受信側が受信データをどのように処理するべきか、そしてなぜそれをマージするのが悪いのかということでした。

0
Duncan