$_REQUEST
ここで、変数を使用しないように言っている投稿をいくつか見ました。私は通常はしませんが、便利な場合もあります。どうしたの?
16 に答える
$_GET
両方から入力を取得しても$_POST
、組み合わせて入力してもまったく問題はありません。実際、それはあなたがほとんど常にやりたいことです:
通常は GET 経由で送信されるプレーンな冪等リクエストの場合、必要なデータの量が URL に収まらない可能性があるため、実際の問題として代わりに POST リクエストに変更されました。
実際に効果のあるリクエストについては、それが POST メソッドによって送信されたことを確認する必要があります。しかし、それを行う方法は、GET が空であることに
$_SERVER['REQUEST_METHOD']
依存するのではなく、明示的にチェックすることです。$_POST
とにかくメソッドPOST
が
いいえ、問題$_REQUEST
は GET パラメータと POST パラメータの混同とは何の関係もありません。デフォルトでは、 も含まれています$_COOKIE
。また、Cookie は実際にはフォーム送信パラメーターとはまったく異なります。それらを同じものとして扱いたいと思うことはほとんどありません。
フォーム パラメータの 1 つと同じ名前の Cookie セットを誤ってサイトに取得した場合、そのパラメータに依存するフォームは、予想されるパラメータを上書きする Cookie 値により、不思議なことに正常に動作しなくなります。同じサイトに複数のアプリがある場合、これは非常に簡単に実行できます。また、使用していない古い Cookie を使用しているユーザーが数人しかいない場合、デバッグが非常に困難になる可能性があります。 -他の1つは再現できます。
PHP 5.3のrequest_order 構成を使用して、この動作をより賢明なGP
(no C
) 順序に変更できます。これが不可能な場合は、個人的には避け、GET + POST 配列を組み合わせて必要な場合は、手動で作成します。$_REQUEST
PHP Internalsに関するいくつかのニュースグループの投稿を掘り下げていたところ、このトピックに関する興味深い議論を見つけました。最初のスレッドは別の話題でしたが、PHP 界のセキュリティ専門家 (ではないにしても) である Stefan Esser の発言により、いくつかの投稿で $_REQUEST を使用することのセキュリティへの影響に議論が向けられました。
$_REQUEST は、PHP の最大の設計上の弱点の 1 つです。$_REQUEST を使用するすべてのアプリケーションは、おそらく遅延クロス サイト リクエスト フォージェリの問題に対して脆弱です。(これは基本的に、(age) という名前の Cookie が存在する場合、常に GET/POST コンテンツを上書きするため、不要なリクエストが実行されることを意味します)
誰かが GET や POST を偽造できるということではありません。クッキー変数。COOKIE が REQUEST の GET および POST データを上書きするという事実についてです。
したがって、ブラウザに action=logout などの Cookie を感染させることができます。その日以降、REQUEST[action] は永久に (Cookie を手動で削除するまで) ログアウトされるため、アプリケーションを使用できなくなります。
COOKIE で感染させるのはとても簡単です...
a) サブドメインのどのアプリケーションでも XSS 脆弱性を使用できます
b) 所有している場合に *.co.uk または *.co.kr の Cookie を設定しようとしたことがありますか?そこに単一のドメイン?
c)その他のクロスドメインの方法...これが問題ではないと思われる場合は、*.co.kr cookie を設定する簡単な方法があることをお伝えします。その結果、いくつかの PHP バージョンではホワイト ページが返されます。想像してみてください: *.co.kr 内のすべての PHP ページを強制終了する 1 つの Cookie だけ
そして、+PHPSESSID= illegalという変数の *.co.kr に対して有効な Cookie に不正なセッション ID を設定することで、PHP セッションを使用して韓国のすべての PHP アプリケーションを引き続き DOS にすることができます...
議論はさらにいくつかの投稿に続き、読むのは興味深いものです。
ご覧のとおり、$_REQUEST の主な問題は、$_GET と $_POST からのデータだけでなく、$_COOKIE からのデータも含まれていることです。リストの他の何人かは、 $_REQUEST が満たされる順序を変更することを提案しました。たとえば、最初に $_COOKIE で満たすなどです。
ただし、 $_REQUEST グローバルから $_COOKIES を完全に省略して、他の配列によって上書きされないようにすることもできます (実際、variable_order ini 設定に関する PHP マニュアルのように、標準コンテンツの任意の組み合わせに制限できます)。教えてくれます:
variable_order EGPCS (Environment、Get、Post、Cookie、および Server) 変数解析の順序を設定します。たとえば、variables_order が "SP" に設定されている場合、PHP はスーパーグローバル $_SERVER と $_POST を作成しますが、$_ENV、$_GET、および $_COOKIE は作成しません。"" に設定すると、スーパーグローバルは設定されません。
ただし、$_REQUEST をまったく使用しないことを検討することもできます。単純に、PHP では、独自のグローバルで Environment、Get、Post、Cookie、および Server にアクセスでき、攻撃ベクトルが 1 つ少なくなるからです。このデータをサニタイズする必要がありますが、心配する必要が 1 つ減ります。
なぜ $_REQUEST が存在し、なぜ削除されないのか疑問に思うかもしれません。これはPHP Internalsでも尋ねられました。$_REQUEST が存在する理由について Rasmus Lerdorf を引用します。PHP 内部について
このようなものを削除すればするほど、より新しく、より高速で、より安全なバージョンの PHP にすばやく移行することが難しくなります。それは、いくつかの「醜い」レガシー機能よりも、誰にとってもフラストレーションを引き起こします。まともな技術的な理由、パフォーマンス、またはセキュリティがある場合は、それを詳しく調べる必要があります. この場合、注目すべきことは、$_REQUEST を削除する必要があるかどうかではなく、そこから Cookie データを削除する必要があるかどうかです。私自身のものを含め、多くの構成はすでにそれを行っており、$_REQUEST に Cookie を含めないことには強力な有効なセキュリティ上の理由があります。ほとんどの人は、$_REQUEST を GET または POST を意味するために使用しますが、これには Cookie も含まれている可能性があるため、悪者が Cookie インジェクション トリックを実行して単純なアプリケーションを破壊する可能性があることに気づいていません。
とにかく、光を当てることを願っています。
$_REQUEST
単純から中程度の複雑さのデータ変換がSQLで宣言されるのではなく、アプリケーションコードで実行されることが多いのと同じ理由で、一般的に有害であると考えられています。
そのため、どこでも使用する傾向がある場合は$_REQUEST
、POSTを介してできることをGETで行うことができます。つまり<img>
、(悪意のある)サイトにタグを設定して、eコマースモジュールにログインしているユーザーがサイレントに製品を購入できるようにします。リンクをクリックすると、危険な行動や機密情報の暴露につながる可能性があります(おそらく私にとって)。
ただし、これは、初心者または少なくとも経験の浅いPHPプログラマーが単純な間違いを犯したためです。まず、どのタイプのデータが適切であるかを把握します。たとえば、URLEncoding、XML、またはJSONで応答を返すことができるWebサービスがあります。アプリケーションは、HTTP_ACCEPTヘッダーをチェックして応答のフォーマット方法を決定しますが、format
パラメーターを送信することで、応答を強制的に1つにまとめることができます。
formatパラメータの内容を確認する場合、呼び出し元のアプリケーションが「&format = json」をリクエストに混ぜたいかどうかなど、さまざまな要因に応じて、クエリ文字列またはpostdataを介して送信できます。この場合、$_REQUEST
次のように入力する手間が省けるので非常に便利です。
$format = isset($_POST['format']) ? $_POST['format']
: (isset($_GET['format']) ? $_GET['format'] : null);
これ以上詳しく説明するつもりはあり$_REQUEST
ませんが、本質的に危険であるため、使用法が思いとどまることはないと言えば十分です。これは、それらの意味を理解しているかどうかに関係なく、求められていることを正確に実行する別のツールです。この問題を引き起こす貧しい、怠惰な、または経験の浅いプログラマーの貧しい、怠惰な、または情報に基づいていない決定。
$_REQUEST
安全に使用する方法
- データを知る:どのような種類のデータを取得するかについてある程度の期待が必要なので、それに応じてサニタイズします。データベースのデータ?
addslashes()
または*_escape_string()
。それをユーザーに表示しますか?htmlentities()
またはhtmlspecialchars()
。数値データを期待していますか?is_numeric()
またはctype_digit()
。実際、filter_input()
およびその関連機能は、データのチェックとサニタイズのみを行うように設計されています。常にこれらのツールを使用してください。 - ユーザー提供のスーパーグローバルデータに直接アクセスしないでください。毎回データをサニタイズする習慣をつけ、データをクリーンな変数に移動します
$post_clean
。または、スーパーグローバルで直接クリーンアップすることもできますが、別の変数を使用することをお勧めする理由は、サニタイズされた同等のものではなく、スーパーグローバルを直接指すものはすべて危険なエラーと見なされるため、コードの脆弱性を簡単に見つけることができるためです。 。 - データの出所を把握します。上記の私の例を参照すると、応答形式変数をGETまたはPOST経由で送信できるようにすることは完全に合理的です。また、「action」変数をどちらの方法でも送信できるようにします。ただし、アクション自体には、どのHTTP動詞が受け入れられるかに関して非常に特定の要件があります。たとえば、サービスで使用されるデータを変更する関数は、POSTを介してのみ送信できます。特定のタイプの非特権データまたは低特権データ(動的に生成されたマップ画像など)の要求は、いずれかの方法からの要求に応じて処理される場合があります。
結論として、この単純なルールを覚えておいてください。
セキュリティはあなたがそれを作るものです、人々!
編集:
bobinceのアドバイスを強くお勧めします。可能であればrequest_order
、php.iniのパラメーターを「GP」に設定します。つまり、Cookieコンポーネントはありません。Cookieデータがクエリ文字列またはpostdataに匹敵すると見なされることはほとんどないため、98%以上のケースでこれを合理的に推論することはほとんどありません。
PS、逸話!
$_REQUEST
超グローバルな方法でアクセス可能なデータを単純に保存する場所を考えているプログラマーを知っていました。重要なユーザー名とパスワード、ファイルへのパス、名前を付けると、に保存されました$_REQUEST
。私がその変数がどのように動作するかを彼に話したとき、彼は少し驚いていました(ただし、残念ながら、コミカルではありませんでした)。言うまでもなく、その慣行は破棄されました。
$_REQUEST
あらゆる種類のリクエスト(GET、POSTなど)を指します。これは便利な場合もありますが、通常は正確なメソッド($ _GET、$ _ POSTなど)を指定する方が適切です。
GET要求はべき等である必要があり、POST要求は通常そうではありません。つまり、データは通常、さまざまな方法で使用する必要があります$_GET
。$_POST
アプリケーションがから$_REQUEST
のデータを使用している場合、GETリクエストとPOSTリクエストの両方で同じように動作し、GETのべき等性に違反します。
あいまいです。post、get、および cookie データを運ぶため、データがどのように取得されたかはわかりません。配送方法を知る必要があるか、制限する必要がない限り、必ずしもそれが悪いことだとは思いません.
私は実際にそれを使うのが好きです。GETまたはPOSTを使用する柔軟性があり、ほとんどの場合データがPOSTされる検索フォームなどに役立ちますが、特定の検索へのリンクを指定したい場合があるため、代わりにGETパラメーターを使用できます。 。
また、他の多くの言語(ASP.NETなど)を見ると、GET変数とPOST変数をまったく区別していません。
ETA:
私はREQUESTを使用してCOOKIE値を取得したことはありませんが、KyleButtはこの投稿へのコメントで素晴らしい点を示していると思います。COOKIE値を取得するためにREQUESTを使用することはお勧めできません。そうすれば、クロスサイトリクエストフォージェリの本当の可能性があると彼は正しいと思います。
また、REQUESTに読み込まれる順序は、php.iniの構成パラメーター(variables_orderおよびrequest_order)によって制御されます。したがって、POSTとGETの両方を介して渡された同じ変数がある場合、実際にREQUESTに入る変数は、それらのini設定によって異なります。特定の順序に依存し、それらの設定が予想とは異なる方法で構成されている場合、これは移植性に影響を与える可能性があります。
$_REQUEST
使用するのは悪い考えではありませんが、GETを使用する場合のみです。
- これを使用してPOST値をロードすると、クロスサイトリクエストフォージェリのリスクがあります
- これを使用してCookie値をロードすると、クロスサイトリクエストフォージェリのリスクが再び発生します
そして、GETを使用しても、入力するのは;)$_GET
よりも短くなります。$_REQUEST
POST を使用するタイミング、GET を使用するタイミング、Cookie を使用するタイミングを理解することが重要です。$_REQUEST を使用すると、見ている値はそれらのいずれかから取得された可能性があります。POST、GET、または COOKIE から値を取得することを期待している場合は、$_REQUEST の代わりに特定の変数を使用する方が、コードを読んでいる人にとってより有益です。
他の誰かが、すべての POST や Cookie を GET でオーバーライドしたくないと指摘しました。たとえば、$_REQUEST を使用しているときに ajax データを返すと、それらすべてに異なるクロスサイト ルールがあるためです。クロスサイトスクリプト攻撃に.
は問題ないと思いますが$_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;
}
}
}
ダレン・クック: 「php 5.3 以降、デフォルトのphp.iniは GETおよびPOST データのみが に入れられると述べています
$_REQUEST
。働いてる!」$_REQUEST
うわー... PHP 5.3 へのアップグレードが原因で、スクリプトの一部が機能しなくなりました。同じことをしました:$_REQUEST
変数を使用するときにCookieが設定されると仮定します。アップグレードすると、まさにそれが機能しなくなりました。
$_COOKIE["Cookie_name"]
私は今、 ...を使用してCookie値を個別に呼び出します
I は、現在の URL またはホスト名を取得する場合にのみ使用される可能性がありますが、& 記号を使用してその URL からパラメーターなどのデータを実際に解析するには、おそらく良い考えではありません。一般に、何をしようとしているのかについて漠然とした説明を使用したくはありません。具体的にする必要がある場合は、$_REQUEST が不適切です。具体的にする必要がない場合は、自由に使用してください。私は思うだろう。
必要なデータがわかっている場合は、明示的に要求する必要があります。IMO、GET、および POST は 2 つの異なる動物であり、投稿データとクエリ文字列を混在させる必要がある正当な理由が思いつきません。持っている人がいたら、興味があります。
スクリプトが同じ方法で GET または POST に応答する可能性がある場合は、$_REQUEST を使用すると便利です。ただし、これは非常にまれなケースであり、ほとんどの場合、2 つの別個の概念を処理するための 2 つの別個の関数、または少なくともメソッドをチェックして正しい変数を選択することが推奨されます。変数がどこから来ているのかを相互参照する必要がない場合、通常、プログラムの流れはずっと簡単に理解できます。コードを 6 か月間保守しなければならない人に親切にしてください。それはあなたかもしれません。
Cookie と REQUEST 変数の環境変数 (GLOBAL を始めないでください) によって引き起こされるセキュリティの問題と WTF に加えて、PHP が PUT や DELETE などの他のメソッドをネイティブにサポートし始めた場合に将来何が起こるかを考えてみてください。これらが REQUEST スーパーグローバルにマージされる可能性は非常に低いですが、variable_order 設定のオプションとして含まれる可能性があります。そのため、特にコードがサードパーティのサーバーにデプロイされている場合は、REQUEST が何を保持しているのか、何が優先されているのかまったくわかりません。
POST は GET よりも安全ですか? あまり。アプリケーションが攻撃されたときに、アプリケーションがどのように悪用されているかをログで簡単に確認できるため、実用的な場合は GET を使用することをお勧めします。スパイダーは通常、ドメインの状態に影響を与える操作には POST が適しています。これは、通常、スパイダーはそれらを追跡せず、CMS にログインしたときに予測フェッチ メカニズムによってすべてのコンテンツが削除されるわけではないためです。ただし、問題は GET と POST のメリットについてではなく、受信者が着信データをどのように処理する必要があるか、およびそれをマージするのがなぜ悪いのかについてだったので、これは実際には単なるところでです。
それは非常に安全ではありません。また、POST、GET、または別のリクエストを受け取っているかどうかわからないため、厄介です。アプリケーションを設計するときは、それらの違いを本当に知っておく必要があります。GETはURLで渡されるため非常に安全ではなく、ページナビゲーション以外のほとんどの用途には適していません。POSTは、それ自体では安全ではありませんが、1つのレベルの安全性を提供します。